Sparse Arrays
Julia поддерживает разреженные векторы и sparse matrices в стандартной библиотеке модуля SparseArrays
. Разреженные массивы — это массивы, которые содержат достаточно нулей, чтобы хранение их в специальной структуре данных приводило к экономии места и времени выполнения по сравнению с плотными массивами.
Внешние пакеты, которые реализуют различные типы разреженного хранения, многомерные разреженные массивы и многое другое, можно найти в Noteworthy External Sparse Packages
Compressed Sparse Column (CSC) Sparse Matrix Storage
В Julia разреженные матрицы хранятся в Compressed Sparse Column (CSC) format. Разреженные матрицы Julia имеют тип SparseMatrixCSC{Tv,Ti}
, где Tv
— это тип хранимых значений, а Ti
— это целочисленный тип для хранения указателей столбцов и индексов строк. Внутреннее представление SparseMatrixCSC
выглядит следующим образом:
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
Сжатое разреженное столбцовое хранилище упрощает и ускоряет доступ к элементам в столбце разреженной матрицы, в то время как доступ к разреженной матрице по строкам значительно медленнее. Операции, такие как вставка ранее не хранившихся записей по одной в структуру CSC, имеют тенденцию быть медленными. Это связано с тем, что все элементы разреженной матрицы, которые находятся за пределами точки вставки, должны быть сдвинуты на одно место.
Все операции с разреженными матрицами тщательно реализованы с учетом структуры данных CSC для повышения производительности и избежания дорогостоящих операций.
Если у вас есть данные в формате CSC из другого приложения или библиотеки и вы хотите импортировать их в Julia, убедитесь, что вы используете индексацию, начинающуюся с 1. Индексы строк в каждом столбце должны быть отсортированы, и если это не так, матрица будет отображаться неправильно. Если ваш объект SparseMatrixCSC
содержит неотсортированные индексы строк, один быстрый способ их отсортировать — это выполнить двойное транспонирование. Поскольку операция транспонирования является ленивой, создайте копию, чтобы материализовать каждое транспонирование.
В некоторых приложениях удобно хранить явные нулевые значения в SparseMatrixCSC
. Эти принимаются функциями в Base
(но нет гарантии, что они будут сохранены в мутирующих операциях). Такие явно хранимые нули рассматриваются как структурные ненулевые значения во многих процедурах. Функция nnz
возвращает количество элементов, явно хранимых в разреженной структуре данных, включая неструктурные нули. Чтобы подсчитать точное количество числовых ненулей, используйте count(!iszero, x)
, которая проверяет каждый хранимый элемент разреженной матрицы. dropzeros
и встроенная dropzeros!
могут быть использованы для удаления хранимых нулей из разреженной матрицы.
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
Разреженные векторы хранятся в близком аналоге формата сжатых разреженных столбцов для разреженных матриц. В Julia разреженные векторы имеют тип SparseVector{Tv,Ti}
, где Tv
— это тип хранимых значений, а Ti
— целочисленный тип для индексов. Внутреннее представление выглядит следующим образом:
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
Что касается SparseMatrixCSC
, тип SparseVector
также может содержать явно хранимые нули. (См. Sparse Matrix Storage.)
Sparse Vector and Matrix Constructors
Самый простой способ создать разреженный массив — использовать функцию, эквивалентную функции zeros
, которую предоставляет Julia для работы с плотными массивами. Чтобы получить разреженный массив, вы можете использовать то же имя с префиксом sp
:
julia> spzeros(3)
3-element SparseVector{Float64, Int64} with 0 stored entries
Функция sparse
часто является удобным способом создания разреженных массивов. Например, для создания разреженной матрицы мы можем ввести вектор I
индексов строк, вектор J
индексов столбцов и вектор V
хранимых значений (это также известно как COO (coordinate) format). sparse(I,J,V)
затем создает разреженную матрицу так, что S[I[k], J[k]] = V[k]
. Эквивалентный конструктор разреженного вектора — sparsevec
, который принимает (строковый) вектор индексов I
и вектор V
с хранимыми значениями и создает разреженный вектор R
так, что 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
Обратная функция sparse
и sparsevec
— это findnz
, которая извлекает входные данные, использованные для создания разреженного массива (включая сохраненные записи, равные нулю). findall(!iszero, x)
возвращает декартовы индексы ненулевых записей в x
(не включая сохраненные записи, равные нулю).
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
Другой способ создать разреженный массив — это преобразовать плотный массив в разреженный массив, используя функцию 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
Вы можете двигаться в другом направлении, используя конструктор Array
. Функцию issparse
можно использовать для запроса, является ли матрица разреженной.
julia> issparse(spzeros(5))
true
Sparse matrix operations
Арифметические операции над разреженными матрицами работают так же, как и над плотными матрицами. Индексация, присваивание и конкатенация разреженных матриц работают так же, как и плотные матрицы. Операции индексации, особенно присваивание, являются дорогими, когда выполняются по одному элементу за раз. Во многих случаях может быть лучше преобразовать разреженную матрицу в формат (I,J,V)
с использованием findnz
, манипулировать значениями или структурой в плотных векторах (I,J,V)
, а затем восстановить разреженную матрицу.
Correspondence of dense and sparse methods
Следующая таблица показывает соответствие между встроенными методами для разреженных матриц и их соответствующими методами для плотных типов матриц. В общем, методы, которые генерируют разреженные матрицы, отличаются от своих плотных аналогов тем, что результирующая матрица следует тому же шаблону разреженности, что и данная разреженная матрица S
, или что результирующая разреженная матрица имеет плотность d
, т.е. каждый элемент матрицы имеет вероятность d
быть ненулевым.
Детали можно найти в разделе Sparse Vectors and Matrices справочника стандартной библиотеки.
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
Разреженные матричные решатели вызывают функции из SuiteSparse. Доступны следующие факторизации:
Type | Description |
---|---|
CHOLMOD.Factor | Cholesky and LDLt factorizations |
UMFPACK.UmfpackLU | LU factorization |
SPQR.QRSparse | QR factorization |
Эти разложения описаны более подробно в Sparse Linear Algebra API section:
SparseArrays API
SparseArrays.AbstractSparseArray
— TypeAbstractSparseArray{Tv,Ti,N}
Супертип для N
-мерных разреженных массивов (или типов, подобных массивам) с элементами типа Tv
и типом индекса Ti
. SparseMatrixCSC
, SparseVector
и SuiteSparse.CHOLMOD.Sparse
являются подтипами этого.
SparseArrays.AbstractSparseVector
— TypeAbstractSparseVector{Tv,Ti}
Супертип для одномерных разреженных массивов (или подобных массивов) с элементами типа Tv
и типом индекса Ti
. Псевдоним для AbstractSparseArray{Tv,Ti,1}
.
SparseArrays.AbstractSparseMatrix
— TypeAbstractSparseMatrix{Tv,Ti}
Супертип для двумерных разреженных массивов (или подобных типов массивов) с элементами типа Tv
и типом индекса Ti
. Псевдоним для AbstractSparseArray{Tv,Ti,2}
.
SparseArrays.SparseVector
— TypeSparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}
Тип вектора для хранения разреженных векторов. Может быть создан путем передачи длины вектора, отсортированного вектора ненулевых индексов и вектора ненулевых значений.
Например, вектор [5, 6, 0, 7]
может быть представлен как
SparseVector(4, [1, 2, 4], [5, 6, 7])
Это указывает на то, что элемент с индексом 1 равен 5, с индексом 2 равен 6, с индексом 3 равен zero(Int)
, а с индексом 4 равен 7.
Может быть удобнее создавать разреженные векторы непосредственно из плотных векторов, используя sparse
, как
sparse([5, 6, 0, 7])
дает тот же разреженный вектор.
SparseArrays.SparseMatrixCSC
— TypeSparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}
Тип матрицы для хранения разреженных матриц в формате Сжатая разреженная колонка. Стандартный способ создания SparseMatrixCSC — через функцию sparse
. См. также spzeros
, spdiagm
и sprand
.
SparseArrays.sparse
— Functionsparse(A)
Преобразует AbstractMatrix A
в разреженную матрицу.
Примеры
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} with 3 stored entries:
1.0 ⋅ ⋅
⋅ 1.0 ⋅
⋅ ⋅ 1.0
sparse(I, J, V,[ m, n, combine])
Создайте разреженную матрицу S
размером m x n
, так что S[I[k], J[k]] = V[k]
. Функция combine
используется для объединения дубликатов. Если m
и n
не указаны, они устанавливаются в maximum(I)
и maximum(J)
соответственно. Если функция combine
не предоставлена, по умолчанию используется +
, если только элементы V
не являются логическими, в этом случае по умолчанию используется |
. Все элементы I
должны удовлетворять 1 <= I[k] <= m
, а все элементы J
должны удовлетворять 1 <= J[k] <= n
. Числовые нули в (I
, J
, V
) сохраняются как структурные ненулевые; чтобы удалить числовые нули, используйте dropzeros!
.
Для дополнительной документации и экспертного драйвера смотрите SparseArrays.sparse!
.
Примеры
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} с 3 сохраненными записями:
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}
Родитель и экспертный драйвер для sparse
; см. sparse
для основного использования. Этот метод позволяет пользователю предоставить предварительно выделенное хранилище для промежуточных объектов и результата sparse
, как описано ниже. Эта возможность позволяет более эффективно последовательно строить SparseMatrixCSC
из координатных представлений, а также позволяет извлекать представление транспонированного результата с несортированными столбцами без дополнительных затрат.
Этот метод состоит из трех основных этапов: (1) Сортировка по количеству предоставленного координатного представления в несортированную строковую форму CSR, включая повторяющиеся записи. (2) Прогулка по форме CSR, одновременно вычисляя массив указателей столбцов желаемой формы CSC, обнаруживая повторяющиеся записи и перепаковывая форму CSR с объединенными повторяющимися записями; этот этап дает несортированную строковую форму CSR без повторяющихся записей. (3) Сортировка по количеству предыдущей формы CSR в полностью отсортированную форму CSC без повторяющихся записей.
Входные массивы csrrowptr
, csrcolval
и csrnzval
составляют хранилище для промежуточных форм CSR и требуют length(csrrowptr) >= m + 1
, length(csrcolval) >= length(I)
, и length(csrnzval >= length(I))
. Входной массив klasttouch
, рабочее пространство для второго этапа, требует length(klasttouch) >= n
. Необязательные входные массивы csccolptr
, cscrowval
и cscnzval
составляют хранилище для возвращаемой формы CSC S
. При необходимости они автоматически изменяются, чтобы удовлетворить length(csccolptr) = n + 1
, length(cscrowval) = nnz(S)
и length(cscnzval) = nnz(S)
; следовательно, если nnz(S)
неизвестен изначально, достаточно передать пустые векторы соответствующего типа (Vector{Ti}()
и Vector{Tv}()
соответственно) или вызвать метод sparse!
, не обращая внимания на cscrowval
и cscnzval
.
При возврате csrrowptr
, csrcolval
и csrnzval
содержат представление транспонированного результата с несортированными столбцами.
Вы можете повторно использовать хранилище входных массивов (I
, J
, V
) для выходных массивов (csccolptr
, cscrowval
, cscnzval
). Например, вы можете вызвать sparse!(I, J, V, csrrowptr, csrcolval, csrnzval, I, J, V)
. Обратите внимание, что они будут изменены, чтобы удовлетворить условия выше.
В интересах эффективности этот метод не выполняет проверку аргументов, кроме 1 <= I[k] <= m
и 1 <= J[k] <= n
. Используйте с осторожностью. Тестирование с --check-bounds=yes
разумно.
Этот метод работает за время O(m, n, length(I))
. Алгоритм HALFPERM, описанный в F. Gustavson, "Два быстрых алгоритма для разреженных матриц: умножение и перестановка," ACM TOMS 4(3), 250-269 (1978), вдохновил использование этого метода пары сортировок по количеству.
SparseArrays.sparse!(I, J, V, [m, n, combine]) -> SparseMatrixCSC
Вариант sparse!
, который повторно использует входные векторы (I
, J
, V
) для хранения конечной матрицы. После построения входные векторы будут ссылаться на буферы матрицы; S.colptr === I
, S.rowval === J
, и S.nzval === V
выполняется, и они будут изменены по мере необходимости.
Обратите внимание, что некоторые рабочие буферы все равно будут выделены. В частности, этот метод является удобной оберткой вокруг sparse!(I, J, V, m, n, combine, klasttouch, csrrowptr, csrcolval, csrnzval, csccolptr, cscrowval, cscnzval)
, где этот метод выделяет klasttouch
, csrrowptr
, csrcolval
и csrnzval
соответствующего размера, но повторно использует I
, J
и V
для csccolptr
, cscrowval
и cscnzval
.
Аргументы m
, n
и combine
по умолчанию равны maximum(I)
, maximum(J)
и +
, соответственно.
Этот метод требует версию Julia 1.10 или новее.
SparseArrays.sparsevec
— Functionsparsevec(I, V, [m, combine])
Создайте разреженный вектор S
длиной m
, такой что S[I[k]] = V[k]
. Дубликаты объединяются с помощью функции combine
, которая по умолчанию равна +
, если аргумент combine
не предоставлен, если только элементы V
не являются логическими значениями, в этом случае combine
по умолчанию равен |
.
Примеры
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])
Создает разреженный вектор длины m
, где ненулевые индексы являются ключами из словаря, а ненулевые значения — значениями из словаря.
Примеры
julia> sparsevec(Dict(1 => 3, 2 => 2))
2-element SparseVector{Int64, Int64} with 2 stored entries:
[1] = 3
[2] = 2
sparsevec(A)
Преобразует вектор A
в разреженный вектор длины m
.
Примеры
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
— Methodаналогичный(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) где {Tv,Ti}
Создает неинициализированный изменяемый массив с заданным типом элемента, типом индекса и размером, основанный на данном источнике SparseMatrixCSC
. Новая разреженная матрица сохраняет структуру оригинальной разреженной матрицы, за исключением случаев, когда размеры выходной матрицы отличаются от выходных.
Выходная матрица имеет нули в тех же местах, что и входная, но неинициализированные значения для ненулевых местоположений.
SparseArrays.issparse
— Functionissparse(S)
Возвращает true
, если S
разреженный, и false
в противном случае.
Примеры
julia> sv = sparsevec([1, 4], [2.3, 2.2], 10)
10-элементный SparseVector{Float64, Int64} с 2 сохраненными записями:
[1] = 2.3
[4] = 2.2
julia> issparse(sv)
true
julia> issparse(Array(sv))
false
SparseArrays.nnz
— Functionnnz(A)
Возвращает количество хранимых (заполненных) элементов в разреженном массиве.
Примеры
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} с 3 хранимыми записями:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> nnz(A)
3
SparseArrays.findnz
— Functionfindnz(A::SparseMatrixCSC)
Возвращает кортеж (I, J, V)
, где I
и J
— это индексы строк и столбцов хранимых ("структурно ненулевых") значений в разреженной матрице A
, а V
— это вектор значений.
Примеры
julia> A = sparse([1 2 0; 0 0 3; 0 4 0])
3×3 SparseMatrixCSC{Int64, Int64} с 4 хранимыми элементами:
1 2 ⋅
⋅ ⋅ 3
⋅ 4 ⋅
julia> findnz(A)
([1, 1, 3, 2], [1, 2, 2, 3], [1, 2, 4, 3])
SparseArrays.spzeros
— Functionspzeros([тип,]m[,n])
Создает разреженный вектор длины m
или разреженную матрицу размера m x n
. Этот разреженный массив не будет содержать никаких ненулевых значений. Во время создания не будет выделено место для ненулевых значений. Тип по умолчанию — Float64
, если не указано иное.
Примеры
julia> spzeros(3, 3)
3×3 SparseMatrixCSC{Float64, Int64} с 0 сохраненными записями:
⋅ ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ ⋅
julia> spzeros(Float32, 4)
4-элементный SparseVector{Float32, Int64} с 0 сохраненными записями
spzeros([type], I::AbstractVector, J::AbstractVector, [m, n])
Создайте разреженную матрицу S
размером m x n
с структурными нулями в S[I[k], J[k]]
.
Этот метод можно использовать для построения структуры разреженности матрицы и он более эффективен, чем, например, sparse(I, J, zeros(length(I)))
.
Для дополнительной документации и экспертного драйвера смотрите SparseArrays.spzeros!
.
Этот метод требует версию Julia 1.10 или новее.
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}
Родитель и экспертный драйвер для spzeros(I, J)
, позволяющий пользователю предоставлять предварительно выделенное хранилище для промежуточных объектов. Этот метод аналогичен spzeros
, как SparseArrays.sparse!
аналогичен sparse
. См. документацию по SparseArrays.sparse!
для получения подробностей и необходимых длин буферов.
Этот метод требует версию Julia 1.10 или новее.
SparseArrays.spzeros!(::Type{Tv}, I, J, [m, n]) -> SparseMatrixCSC{Tv}
Вариант spzeros!
, который повторно использует входные векторы I
и J
для хранения конечной матрицы. После построения входные векторы будут ссылаться на буферы матрицы; S.colptr === I
и S.rowval === J
выполняется, и они будут изменены с помощью resize!
по мере необходимости.
Обратите внимание, что некоторые рабочие буферы все еще будут выделены. В частности, этот метод является удобной оберткой вокруг spzeros!(Tv, I, J, m, n, klasttouch, csrrowptr, csrcolval, csccolptr, cscrowval)
, где этот метод выделяет klasttouch
, csrrowptr
и csrcolval
соответствующего размера, но повторно использует I
и J
для csccolptr
и cscrowval
.
Аргументы m
и n
по умолчанию равны maximum(I)
и maximum(J)
.
Этот метод требует версию Julia 1.10 или новее.
SparseArrays.spdiagm
— Functionspdiagm(kv::Pair{<:Integer,<:AbstractVector}...)
spdiagm(m::Integer, n::Integer, kv::Pair{<:Integer,<:AbstractVector}...)
Создайте разреженную диагональную матрицу из `Pair` векторов и диагоналей. Каждый вектор `kv.second` будет размещен на диагонали `kv.first`. По умолчанию матрица квадратная, и ее размер определяется из `kv`, но можно указать прямоугольный размер `m`×`n` (дополненный нулями по мере необходимости), передав `m,n` в качестве первых аргументов.
# Примеры
jldoctest julia> spdiagm(-1 => [1,2,3,4], 1 => [4,3,2,1]) 5×5 SparseMatrixCSC{Int64, Int64} с 8 сохраненными элементами: ⋅ 4 ⋅ ⋅ ⋅ 1 ⋅ 3 ⋅ ⋅ ⋅ 2 ⋅ 2 ⋅ ⋅ ⋅ 3 ⋅ 1 ⋅ ⋅ ⋅ 4 ⋅ ```
spdiagm(v::AbstractVector)
spdiagm(m::Integer, n::Integer, v::AbstractVector)
Создает разреженную матрицу с элементами вектора в качестве диагональных элементов. По умолчанию (без указанных m
и n
) матрица квадратная, и ее размер задается length(v)
, но можно указать прямоугольный размер m
×n
, передав m
и n
в качестве первых аргументов.
Эти функции требуют как минимум Julia 1.6.
Примеры
julia> spdiagm([1,2,3])
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
1 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 3
julia> spdiagm(sparse([1,0,3]))
3×3 SparseMatrixCSC{Int64, Int64} with 2 stored entries:
1 ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ 3
SparseArrays.sparse_hcat
— Functionsparse_hcat(A...)
Объединить вдоль размерности 2. Вернуть объект SparseMatrixCSC.
Этот метод был добавлен в Julia 1.8. Он имитирует предыдущее поведение объединения, при котором объединение со специализированными типами "разреженных" матриц из LinearAlgebra.jl автоматически давало разреженный вывод даже при отсутствии аргумента SparseArray.
SparseArrays.sparse_vcat
— Functionsparse_vcat(A...)
Объединить вдоль размерности 1. Вернуть объект SparseMatrixCSC.
Этот метод был добавлен в Julia 1.8. Он имитирует предыдущее поведение объединения, при котором объединение со специализированными типами "разреженных" матриц из LinearAlgebra.jl автоматически давало разреженный вывод даже при отсутствии аргумента SparseArray.
SparseArrays.sparse_hvcat
— Functionsparse_hvcat(rows::Tuple{Vararg{Int}}, values...)
Разреженная горизонтальная и вертикальная конкатенация в одном вызове. Эта функция вызывается для синтаксиса блочной матрицы. Первый аргумент указывает количество аргументов для конкатенации в каждой блочной строке.
Этот метод был добавлен в Julia 1.8. Он имитирует предыдущее поведение конкатенации, при котором конкатенация со специализированными типами "разреженных" матриц из LinearAlgebra.jl автоматически давала разреженный вывод даже при отсутствии аргумента SparseArray.
SparseArrays.blockdiag
— Functionblockdiag(A...)
Объединяет матрицы по блочной диагонали. В настоящее время реализовано только для разреженных матриц.
Примеры
julia> blockdiag(sparse(2I, 3, 3), sparse(4I, 2, 2))
5×5 SparseMatrixCSC{Int64, Int64} with 5 stored entries:
2 ⋅ ⋅ ⋅ ⋅
⋅ 2 ⋅ ⋅ ⋅
⋅ ⋅ 2 ⋅ ⋅
⋅ ⋅ ⋅ 4 ⋅
⋅ ⋅ ⋅ ⋅ 4
SparseArrays.sprand
— Functionsprand([rng],[T::Type],m,[n],p::AbstractFloat)
sprand([rng],m,[n],p::AbstractFloat,[rfn=rand])
Создает разреженный вектор длины m
или разреженную матрицу m
на n
, в которой вероятность того, что любой элемент будет ненулевым, независимо задана p
(и, следовательно, средняя плотность ненулевых значений также точно равна p
). Необязательный аргумент rng
указывает генератор случайных чисел, см. Случайные числа. Необязательный аргумент T
указывает тип элемента, который по умолчанию равен Float64
.
По умолчанию ненулевые значения выбираются из равномерного распределения с использованием функции rand
, т.е. с помощью rand(T)
, или rand(rng, T)
, если rng
указан; для значения по умолчанию T=Float64
это соответствует ненулевым значениям, равномерно распределенным в [0,1)
.
Вы можете выбирать ненулевые значения из другого распределения, передав пользовательскую функцию rfn
вместо rand
. Это должна быть функция rfn(k)
, которая возвращает массив из k
случайных чисел, выбранных из желаемого распределения; альтернативно, если rng
указан, это должна быть функция rfn(rng, k)
.
Примеры
julia> sprand(Bool, 2, 2, 0.5)
2×2 SparseMatrixCSC{Bool, Int64} с 2 сохраненными записями:
1 1
⋅ ⋅
julia> sprand(Float64, 3, 0.75)
3-элементный SparseVector{Float64, Int64} с 2 сохраненными записями:
[1] = 0.795547
[2] = 0.49425
SparseArrays.sprandn
— Functionsprandn([rng][,Type],m[,n],p::AbstractFloat)
Создает случайный разреженный вектор длины m
или разреженную матрицу размера m
на n
с заданной (независимой) вероятностью p
того, что любое значение будет ненулевым, где ненулевые значения выбираются из нормального распределения. Необязательный аргумент rng
указывает генератор случайных чисел, см. Случайные числа.
Указание типа элемента выходных данных Type
требует как минимум Julia 1.1.
Примеры
julia> sprandn(2, 2, 0.75)
2×2 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
-1.20577 ⋅
0.311817 -0.234641
SparseArrays.nonzeros
— Functionnonzeros(A)
Возвращает вектор структурных ненулевых значений в разреженном массиве A
. Это включает нули, которые явно хранятся в разреженном массиве. Возвращаемый вектор указывает непосредственно на внутреннее ненулевое хранилище A
, и любые изменения в возвращаемом векторе также изменят A
. См. rowvals
и nzrange
.
Примеры
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} с 3 хранимыми записями:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> nonzeros(A)
3-элементный вектор{Int64}:
2
2
2
SparseArrays.rowvals
— Functionrowvals(A::AbstractSparseMatrixCSC)
Возвращает вектор индексов строк матрицы A
. Любые изменения в возвращаемом векторе также изменят A
. Предоставление доступа к тому, как индексы строк хранятся внутри, может быть полезным в сочетании с итерацией по структурным ненулевым значениям. См. также nonzeros
и nzrange
.
Примеры
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} с 3 сохраненными элементами:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> rowvals(A)
3-element Vector{Int64}:
1
2
3
SparseArrays.nzrange
— Functionnzrange(A::AbstractSparseMatrixCSC, col::Integer)
Возвращает диапазон индексов для структурных ненулевых значений столбца разреженной матрицы. В сочетании с nonzeros
и rowvals
это позволяет удобно итерировать по разреженной матрице:
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]
# выполняйте разреженные волшебства...
end
end
Добавление или удаление ненулевых элементов в матрицу может сделать nzrange
недействительным, не следует изменять матрицу во время итерации.
nzrange(x::SparseVectorUnion, col)
Дает диапазон индексов для структурных ненулевых значений разреженного вектора. Индекс столбца col
игнорируется (предполагается, что он равен 1
).
SparseArrays.droptol!
— Functiondroptol!(A::AbstractSparseMatrixCSC, tol)
Удаляет сохраненные значения из A
, абсолютное значение которых меньше или равно tol
.
droptol!(x::AbstractCompressedVector, tol)
Удаляет сохраненные значения из x
, абсолютное значение которых меньше или равно tol
.
SparseArrays.dropzeros!
— Functiondropzeros!(x::AbstractCompressedVector)
Удаляет сохраненные числовые нули из x
.
Для версии без изменения, смотрите dropzeros
. Для алгоритмической информации смотрите fkeep!
.
SparseArrays.dropzeros
— Functiondropzeros(A::AbstractSparseMatrixCSC;)
Создает копию A
и удаляет сохраненные числовые нули из этой копии.
Для версии с изменением на месте и алгоритмической информации смотрите dropzeros!
.
Примеры
julia> A = sparse([1, 2, 3], [1, 2, 3], [1.0, 0.0, 1.0])
3×3 SparseMatrixCSC{Float64, Int64} с 3 сохраненными записями:
1.0 ⋅ ⋅
⋅ 0.0 ⋅
⋅ ⋅ 1.0
julia> dropzeros(A)
3×3 SparseMatrixCSC{Float64, Int64} с 2 сохраненными записями:
1.0 ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ 1.0
dropzeros(x::AbstractCompressedVector)
Создает копию x
и удаляет числовые нули из этой копии.
Для версии с изменением на месте и алгоритмической информации смотрите dropzeros!
.
Примеры
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}
Двусторонняя перестановка A
, возвращающая PAQ
(A[p,q]
). Длина перестановки по столбцам q
должна соответствовать количеству столбцов A
(length(q) == size(A, 2)
). Длина перестановки по строкам p
должна соответствовать количеству строк A
(length(p) == size(A, 1)
).
Для опытных пользователей и дополнительной информации смотрите permute!
.
Примеры
julia> A = spdiagm(0 => [1, 2, 3, 4], 1 => [5, 6, 7])
4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:
1 5 ⋅ ⋅
⋅ 2 6 ⋅
⋅ ⋅ 3 7
⋅ ⋅ ⋅ 4
julia> permute(A, [4, 3, 2, 1], [1, 2, 3, 4])
4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:
⋅ ⋅ ⋅ 4
⋅ ⋅ 3 7
⋅ 2 6 ⋅
1 5 ⋅ ⋅
julia> permute(A, [1, 2, 3, 4], [4, 3, 2, 1])
4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:
⋅ ⋅ 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}
Двусторонняя перестановка A
, сохранение результата PAQ
(A[p,q]
) в X
. Сохраняет промежуточный результат (AQ)^T
(transpose(A[:,q])
) в необязательном аргументе C
, если он присутствует. Требуется, чтобы ни X
, ни A
, а также, если присутствует, C
не ссылались друг на друга; чтобы сохранить результат PAQ
обратно в A
, используйте следующий метод без X
:
permute!(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},
q::AbstractVector{<:Integer}[, C::AbstractSparseMatrixCSC{Tv,Ti},
[workcolptr::Vector{Ti}]]) where {Tv,Ti}
Размеры X
должны соответствовать размерам A
(size(X, 1) == size(A, 1)
и size(X, 2) == size(A, 2)
), и X
должен иметь достаточно места для размещения всех выделенных записей в A
(length(rowvals(X)) >= nnz(A)
и length(nonzeros(X)) >= nnz(A)
). Длина перестановки по столбцам q
должна соответствовать количеству столбцов в A
(length(q) == size(A, 2)
). Длина перестановки по строкам p
должна соответствовать количеству строк в A
(length(p) == size(A, 1)
).
Размеры C
должны соответствовать размерам transpose(A)
(size(C, 1) == size(A, 2)
и size(C, 2) == size(A, 1)
), и C
должен иметь достаточно места для размещения всех выделенных записей в A
(length(rowvals(C)) >= nnz(A)
и length(nonzeros(C)) >= nnz(A)
).
Для дополнительной (алгоритмической) информации и для версий этих методов, которые не проверяют аргументы, смотрите (неэкспортированные) родительские методы unchecked_noalias_permute!
и unchecked_aliasing_permute!
.
Смотрите также permute
.
SparseArrays.halfperm!
— Functionhalfperm!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{TvA,Ti},
q::AbstractVector{<:Integer}, f::Function = identity) where {Tv,TvA,Ti}
Поменять местами столбцы и транспонировать A
, одновременно применяя f
к каждому элементу A
, сохраняя результат (f(A)Q)^T
(map(f, transpose(A[:,q]))
) в X
.
Тип элемента Tv
в X
должен соответствовать f(::TvA)
, где TvA
— это тип элемента A
. Размеры X
должны соответствовать размерам transpose(A
(size(X, 1) == size(A, 2)
и size(X, 2) == size(A, 1)
), и X
должен иметь достаточно места для размещения всех выделенных элементов в A
(length(rowvals(X)) >= nnz(A)
и length(nonzeros(X)) >= nnz(A)
). Длина перестановки столбцов q
должна соответствовать количеству столбцов в A
(length(q) == size(A, 2)
).
Этот метод является родительским для нескольких методов, выполняющих операции транспонирования и перестановки над SparseMatrixCSC
. Поскольку этот метод не выполняет проверку аргументов, предпочтительнее использовать более безопасные дочерние методы ([c]transpose[!]
, permute[!]
) вместо прямого использования.
Этот метод реализует алгоритм HALFPERM
, описанный в F. Gustavson, "Два быстрых алгоритма для разреженных матриц: умножение и перестановленная транспонирование," ACM TOMS 4(3), 250-269 (1978). Алгоритм работает за время O(size(A, 1), size(A, 2), nnz(A))
и не требует дополнительного пространства, кроме переданного.
SparseArrays.ftranspose!
— Functionftranspose!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}, f::Function) where {Tv,Ti}
Транспонирует A
и сохраняет его в X
, применяя функцию f
к ненулевым элементам. Не удаляет нули, созданные f
. size(X)
должен быть равен size(transpose(A))
. Дополнительная память не выделяется, кроме изменения размера rowval и nzval X
, если это необходимо.
См. halfperm!
Sparse Linear Algebra API
LinearAlgebra.cholesky
— Functioncholesky(A, NoPivot(); check = true) -> Cholesky
Вычисляет разложение Холецкого плотной симметричной положительно определенной матрицы A
и возвращает Cholesky
разложение. Матрица A
может быть либо Symmetric
, либо Hermitian
AbstractMatrix
или совершенно симметричной или эрмитовой AbstractMatrix
.
Треугольный фактор Холецкого можно получить из разложения F
с помощью F.L
и F.U
, где A ≈ F.U' * F.U ≈ F.L * F.L'
.
Следующие функции доступны для объектов Cholesky
: size
, \
, inv
, det
, logdet
и isposdef
.
Если у вас есть матрица A
, которая немного не является эрмитовой из-за ошибок округления при ее построении, оберните ее в Hermitian(A)
перед передачей в cholesky
, чтобы рассматривать ее как совершенно эрмитовую.
Когда check = true
, возникает ошибка, если разложение не удалось. Когда check = false
, ответственность за проверку действительности разложения (с помощью issuccess
) лежит на пользователе.
Примеры
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 фактор:
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
Вычисляет разложение по методу Холецкого с учетом перестановок для плотной симметричной положительно полупределенной матрицы A
и возвращает разложение CholeskyPivoted
. Матрица A
может быть либо Symmetric
, либо Hermitian
AbstractMatrix
или совершенно симметричной или эрмитовой AbstractMatrix
.
Треугольный фактор Холецкого можно получить из разложения F
с помощью F.L
и F.U
, а перестановку — с помощью F.p
, где A[F.p, F.p] ≈ Ur' * Ur ≈ Lr * Lr'
с Ur = F.U[1:F.rank, :]
и Lr = F.L[:, 1:F.rank]
, или альтернативно A ≈ Up' * Up ≈ Lp * Lp'
с Up = F.U[1:F.rank, invperm(F.p)]
и Lp = F.L[invperm(F.p), 1:F.rank]
.
Следующие функции доступны для объектов CholeskyPivoted
: size
, \
, inv
, det
и rank
.
Аргумент tol
определяет допустимую погрешность для определения ранга. Для отрицательных значений допустимая погрешность равна машинной точности.
Если у вас есть матрица A
, которая слегка не является эрмитовой из-за ошибок округления при ее построении, оберните ее в Hermitian(A)
перед передачей в cholesky
, чтобы рассматривать ее как совершенно эрмитовую.
Когда check = true
, возникает ошибка, если разложение не удалось. Когда check = false
, ответственность за проверку корректности разложения (с помощью issuccess
) лежит на пользователе.
Примеры
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 фактор с рангом 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
перестановка:
4-элементный вектор 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; # деструктуризация через итерацию
julia> l == C.L && u == C.U
true
cholesky(A::SparseMatrixCSC; shift = 0.0, check = true, perm = nothing) -> CHOLMOD.Factor
Вычисляет разложение Холецкого разреженной положительно определенной матрицы A
. A
должна быть SparseMatrixCSC
или Symmetric
/Hermitian
представлением SparseMatrixCSC
. Обратите внимание, что даже если у A
нет типа, она все равно должна быть симметричной или эрмитовой. Если perm
не задан, используется перестановка, уменьшающая заполнение. F = cholesky(A)
чаще всего используется для решения систем уравнений с F\b
, но также методы diag
, det
и logdet
определены для F
. Вы также можете извлечь отдельные факторы из F
, используя F.L
. Однако, поскольку поворот включен по умолчанию, разложение внутренне представлено как A == P'*L*L'*P
с матрицей перестановки P
; использование только L
без учета P
даст неправильные ответы. Чтобы учесть эффекты перестановки, обычно предпочтительно извлекать "комбинированные" факторы, такие как PtL = F.PtL
(эквивалент P'*L
) и LtP = F.UP
(эквивалент L'*P
).
Когда check = true
, возникает ошибка, если разложение не удалось. Когда check = false
, ответственность за проверку действительности разложения (через issuccess
) лежит на пользователе.
Установка необязательного аргумента ключевого слова shift
вычисляет разложение A+shift*I
вместо A
. Если аргумент perm
предоставлен, он должен быть перестановкой 1:size(A,1)
, задающей порядок, который следует использовать (вместо стандартного порядка AMD от CHOLMOD).
Примеры
В следующем примере используемая перестановка, уменьшающая заполнение, равна [3, 2, 1]
. Если perm
установлен на 1:3
, чтобы не применять перестановку, количество ненулевых элементов в факторе равно 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} with 3 stored entries:
⋅ ⋅ 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
Этот метод использует библиотеку CHOLMOD[ACM887][DavisHager2009] из SuiteSparse. CHOLMOD поддерживает только действительные или комплексные типы в одинарной или двойной точности. Входные матрицы, не относящиеся к этим типам элементов, будут преобразованы в эти типы по мере необходимости.
Многие другие функции из CHOLMOD обернуты, но не экспортированы из модуля Base.SparseArrays.CHOLMOD
.
LinearAlgebra.cholesky!
— Functioncholesky!(A::AbstractMatrix, NoPivot(); check = true) -> Cholesky
То же самое, что и cholesky
, но экономит место, перезаписывая входной A
, вместо создания копии. Исключение InexactError
выбрасывается, если факторизация производит число, которое не может быть представлено типом элемента A
, например, для целочисленных типов.
Примеры
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
То же самое, что и cholesky
, но экономит место, перезаписывая входной A
, вместо создания копии. Исключение InexactError
выбрасывается, если факторизация производит число, которое не может быть представлено типом элемента A
, например, для целочисленных типов.
cholesky!(F::CHOLMOD.Factor, A::SparseMatrixCSC; shift = 0.0, check = true) -> CHOLMOD.Factor
Вычисляет разложение Холецкого ($LL'$) матрицы A
, повторно используя символическое разложение F
. A
должна быть SparseMatrixCSC
или Symmetric
/ Hermitian
представлением SparseMatrixCSC
. Обратите внимание, что даже если у A
нет типа, она все равно должна быть симметричной или эрмитовой.
Смотрите также cholesky
.
Этот метод использует библиотеку CHOLMOD из SuiteSparse, которая поддерживает только вещественные или комплексные типы в одинарной или двойной точности. Входные матрицы, не относящиеся к этим типам элементов, будут преобразованы в эти типы по мере необходимости.
LinearAlgebra.lowrankupdate
— Functionlowrankupdate(C::Cholesky, v::AbstractVector) -> CC::Cholesky
Обновите разложение Холецкого C
с вектором v
. Если A = C.U'C.U
, то CC = cholesky(C.U'C.U + v*v')
, но вычисление CC
использует только O(n^2)
операций.
lowrankupdate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.Factor
Получите LDLt
факторизацию A + C*C'
, учитывая LDLt
или LLt
факторизацию F
для A
.
Возвращаемый фактор всегда является LDLt
факторизацией.
Смотрите также lowrankupdate!
, lowrankdowndate
, lowrankdowndate!
.
LinearAlgebra.lowrankupdate!
— Functionlowrankupdate!(C::Cholesky, v::AbstractVector) -> CC::Cholesky
Обновите разложение Холецкого C
с вектором v
. Если A = C.U'C.U
, то CC = cholesky(C.U'C.U + v*v')
, но вычисление CC
использует только O(n^2)
операций. Входное разложение C
обновляется на месте так, что при выходе C == CC
. Вектор v
уничтожается во время вычисления.
lowrankupdate!(F::CHOLMOD.Factor, C::AbstractArray)
Обновляет LDLt
или LLt
факторизацию F
матрицы A
до факторизации матрицы A + C*C'
.
Факторизации LLt
преобразуются в LDLt
.
Смотрите также lowrankupdate
, lowrankdowndate
, lowrankdowndate!
.
LinearAlgebra.lowrankdowndate
— Functionlowrankdowndate(C::Cholesky, v::AbstractVector) -> CC::Cholesky
Снизить ранг разложения Холецкого C
с вектором v
. Если A = C.U'C.U
, то CC = cholesky(C.U'C.U - v*v')
, но вычисление CC
использует только O(n^2)
операций.
lowrankdowndate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.Factor
Получите LDLt
факторизацию A + C*C'
, учитывая LDLt
или LLt
факторизацию F
от A
.
Возвращаемый фактор всегда является LDLt
факторизацией.
Смотрите также lowrankdowndate!
, lowrankupdate
, lowrankupdate!
.
LinearAlgebra.lowrankdowndate!
— Functionlowrankdowndate!(C::Cholesky, v::AbstractVector) -> CC::Cholesky
Обновление разложения Холецкого C
с вектором v
. Если A = C.U'C.U
, то CC = cholesky(C.U'C.U - v*v')
, но вычисление CC
использует только O(n^2)
операций. Входное разложение C
обновляется на месте, так что при выходе C == CC
. Вектор v
уничтожается во время вычисления.
lowrankdowndate!(F::CHOLMOD.Factor, C::AbstractArray)
Обновляет разложение LDLt
или LLt
F
матрицы A
до разложения матрицы A - C*C'
.
Разложения LLt
преобразуются в LDLt
.
Смотрите также lowrankdowndate
, lowrankupdate
, lowrankupdate!
.
SparseArrays.CHOLMOD.lowrankupdowndate!
— Functionlowrankupdowndate!(F::CHOLMOD.Factor, C::Sparse, update::Cint)
Обновите факторизацию LDLt
или LLt
F
матрицы A
до факторизации A ± C*C'
.
Если используется разреженная факторизация, т.е. L*L' == P*A*P'
, то новая факторизация будет L*L' == P*A*P' + C'*C
update
: Cint(1)
для A + CC'
, Cint(0)
для A - CC'
LinearAlgebra.ldlt
— Functionldlt(S::SymTridiagonal) -> LDLt
Вычисляет разложение LDLt
(т.е. $LDL^T$) для действительной симметричной тридиагональной матрицы S
, такое что S = L*Diagonal(d)*L'
, где L
— это единичная нижняя треугольная матрица, а d
— вектор. Основное применение разложения LDLt
F = ldlt(S)
заключается в решении системы линейных уравнений Sx = b
с помощью F\b
.
Смотрите также bunchkaufman
для аналогичного, но с поворотом, разложения произвольных симметричных или эрмитовых матриц.
Примеры
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
Вычисляет факторизацию $LDL'$ разреженной матрицы A
. A
должна быть SparseMatrixCSC
или Symmetric
/Hermitian
представлением SparseMatrixCSC
. Обратите внимание, что даже если у A
нет типа, она все равно должна быть симметричной или эрмитовой. Используется перестановка, уменьшающая заполнение. F = ldlt(A)
чаще всего используется для решения систем уравнений A*x = b
с помощью F\b
. Возвращаемый объект факторизации F
также поддерживает методы diag
, det
, logdet
и inv
. Вы можете извлечь отдельные факторы из F
, используя F.L
. Однако, поскольку поворот включен по умолчанию, факторизация внутренне представлена как A == P'*L*D*L'*P
с матрицей перестановки P
; использование только L
без учета P
даст неправильные ответы. Чтобы учесть эффекты перестановки, обычно предпочтительно извлекать "комбинированные" факторы, такие как PtL = F.PtL
(эквивалент P'*L
) и LtP = F.UP
(эквивалент L'*P
). Полный список поддерживаемых факторов: :L, :PtL, :D, :UP, :U, :LD, :DU, :PtLD, :DUP
.
Когда check = true
, возникает ошибка, если разложение не удалось. Когда check = false
, ответственность за проверку действительности разложения (через issuccess
) лежит на пользователе.
Установка необязательного аргумента shift
вычисляет факторизацию A+shift*I
вместо A
. Если аргумент perm
предоставлен, он должен быть перестановкой 1:size(A,1)
, задающей порядок, который следует использовать (вместо стандартного порядка AMD от CHOLMOD).
Этот метод использует библиотеку CHOLMOD[ACM887][DavisHager2009] из SuiteSparse. CHOLMOD поддерживает только действительные или комплексные типы в одинарной или двойной точности. Входные матрицы, не относящиеся к этим типам элементов, будут преобразованы в эти типы по мере необходимости.
Многие другие функции из CHOLMOD обернуты, но не экспортированы из модуля Base.SparseArrays.CHOLMOD
.
LinearAlgebra.lu
— Functionlu(A::AbstractSparseMatrixCSC; check = true, q = nothing, control = get_umfpack_control()) -> F::UmfpackLU
Вычисляет LU-разложение разреженной матрицы A
.
Для разреженной A
с элементами типа real или complex, возвращаемый тип F
— это UmfpackLU{Tv, Ti}
, где Tv
= Float64
или ComplexF64
соответственно, а Ti
— это целочисленный тип (Int32
или Int64
).
Когда check = true
, возникает ошибка, если разложение не удалось. Когда check = false
, ответственность за проверку корректности разложения (через issuccess
) лежит на пользователе.
Перестановка q
может быть либо вектором перестановки, либо nothing
. Если вектор перестановки не предоставлен или q
равно nothing
, используется значение по умолчанию UMFPACK. Если перестановка не основана на нуле, создается копия, основанная на нуле.
Вектор control
по умолчанию соответствует конфигурации по умолчанию пакета Julia SparseArrays для UMFPACK (NB: это изменено из значений по умолчанию UMFPACK для отключения итеративной доработки), но может быть изменен путем передачи вектора длиной UMFPACK_CONTROL
, см. руководство UMFPACK для возможных конфигураций. Например, чтобы повторно включить итеративную доработку:
umfpack_control = SparseArrays.UMFPACK.get_umfpack_control(Float64, Int64) # прочитать конфигурацию по умолчанию Julia для разреженной матрицы Float64
SparseArrays.UMFPACK.show_umf_ctrl(umfpack_control) # необязательно - отобразить значения
umfpack_control[SparseArrays.UMFPACK.JL_UMFPACK_IRSTEP] = 2.0 # повторно включить итеративную доработку (2 - это максимальное количество итеративных шагов по умолчанию UMFPACK)
Alu = lu(A; control = umfpack_control)
x = Alu \ b # решить Ax = b, включая итеративную доработку UMFPACK
Индивидуальные компоненты разложения F
могут быть доступны через индексацию:
Компонент | Описание |
---|---|
L | L (нижняя треугольная) часть LU |
U | U (верхняя треугольная) часть LU |
p | правая перестановка Vector |
q | левая перестановка Vector |
Rs | Vector коэффициентов масштабирования |
: | компоненты (L,U,p,q,Rs) |
Связь между F
и A
следующая:
F.L*F.U == (F.Rs .* A)[F.p, F.q]
F
также поддерживает следующие функции:
См. также lu!
lu(A::AbstractSparseMatrixCSC)
использует библиотеку UMFPACK[ACM832], которая является частью SuiteSparse. Поскольку эта библиотека поддерживает только разреженные матрицы с элементами Float64
или ComplexF64
, lu
преобразует A
в копию, которая имеет тип SparseMatrixCSC{Float64}
или SparseMatrixCSC{ComplexF64}
в зависимости от ситуации.
lu(A, pivot = RowMaximum(); check = true, allowsingular = false) -> F::LU
Вычисляет LU-разложение A
.
Когда check = true
, возникает ошибка, если разложение не удалось. Когда check = false
, ответственность за проверку действительности разложения (через issuccess
) лежит на пользователе.
По умолчанию, при check = true
, также возникает ошибка, когда разложение дает действительные факторы, но верхняя треугольная матрица U
имеет недостаточный ранг. Это можно изменить, передав allowsingular = true
.
В большинстве случаев, если A
является подтипом S
от AbstractMatrix{T}
с типом элемента T
, поддерживающим +
, -
, *
и /
, возвращаемый тип будет LU{T,S{T}}
.
В общем, LU-разложение включает перестановку строк матрицы (соответствующую выходу F.p
, описанному ниже), известную как "пивотирование" (потому что это соответствует выбору, какая строка содержит "пивот", диагональный элемент F.U
). Одна из следующих стратегий пивотирования может быть выбрана через необязательный аргумент pivot
:
RowMaximum()
(по умолчанию): стандартная стратегия пивотирования; пивот соответствует элементу с максимальным абсолютным значением среди оставшихся строк, которые нужно разложить. Эта стратегия пивотирования требует, чтобы тип элемента также поддерживалabs
и<
. (Это, как правило, единственный численно стабильный вариант для матриц с плавающей запятой.)RowNonZero()
: пивот соответствует первому ненулевому элементу среди оставшихся строк, которые нужно разложить. (Это соответствует типичному выбору в ручных расчетах и также полезно для более общих алгебраических типов чисел, которые поддерживаютiszero
, но неabs
или<
.)NoPivot()
: пивотирование отключено (не удастся, если в позиции пивота встретится нулевой элемент, даже когдаallowsingular = true
).
Индивидуальные компоненты разложения F
можно получить через getproperty
:
Компонент | Описание |
---|---|
F.L | L (нижняя треугольная) часть LU |
F.U | U (верхняя треугольная) часть LU |
F.p | (правое) перестановка Vector |
F.P | (правое) перестановка Matrix |
Итерация по разложению производит компоненты F.L
, F.U
и F.p
.
Связь между F
и A
такова:
F.L*F.U == A[F.p, :]
F
дополнительно поддерживает следующие функции:
Поддерживаемая функция | LU | LU{T,Tridiagonal{T}} |
---|---|---|
/ | ✓ | |
\ | ✓ | ✓ |
inv | ✓ | ✓ |
det | ✓ | ✓ |
logdet | ✓ | ✓ |
logabsdet | ✓ | ✓ |
size | ✓ | ✓ |
Аргумент ключевого слова allowsingular
был добавлен в Julia 1.11.
Примеры
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 фактор:
2×2 Matrix{Float64}:
1.0 0.0
0.666667 1.0
U фактор:
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); # деструктуризация через итерацию
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 фактор:
2×2 Matrix{Float64}:
1.0 0.0
1.0 1.0
U фактор (с недостаточным рангом):
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
Вычисляет QR
разложение разреженной матрицы A
. Используются перестановки строк и столбцов, уменьшающие заполнение, так что F.R = F.Q'*A[F.prow,F.pcol]
. Основное применение этого типа заключается в решении задач наименьших квадратов или недоопределенных задач с помощью \
. Функция вызывает библиотеку C SPQR[ACM933].
qr(A::SparseMatrixCSC)
использует библиотеку SPQR, которая является частью SuiteSparse. Поскольку эта библиотека поддерживает только разреженные матрицы с элементами Float64
или ComplexF64
, начиная с Julia v1.4 qr
преобразует A
в копию, которая имеет тип SparseMatrixCSC{Float64}
или SparseMatrixCSC{ComplexF64}
в зависимости от ситуации.
Примеры
julia> A = sparse([1,2,3,4], [1,1,2,2], [1.0,1.0,1.0,1.0])
4×2 SparseMatrixCSC{Float64, Int64} с 4 сохраненными элементами:
1.0 ⋅
1.0 ⋅
⋅ 1.0
⋅ 1.0
julia> qr(A)
SparseArrays.SPQR.QRSparse{Float64, Int64}
Q фактор:
4×4 SparseArrays.SPQR.QRSparseQ{Float64, Int64}
R фактор:
2×2 SparseMatrixCSC{Float64, Int64} с 2 сохраненными элементами:
-1.41421 ⋅
⋅ -1.41421
Перестановка строк:
4-элементный вектор{Int64}:
1
3
4
2
Перестановка столбцов:
2-элементный вектор{Int64}:
1
2
qr(A, pivot = NoPivot(); blocksize) -> F
Вычисляет QR-разложение матрицы A
: ортогональная (или унитарная, если A
имеет комплексные значения) матрица Q
и верхняя треугольная матрица R
, такая что
\[A = Q R\]
Возвращаемый объект F
хранит разложение в упакованном формате:
- если
pivot == ColumnNorm()
, тоF
является объектомQRPivoted
, - в противном случае, если элемент типа
A
является типом BLAS (Float32
,Float64
,ComplexF32
илиComplexF64
), тоF
является объектомQRCompactWY
, - в противном случае
F
является объектомQR
.
Индивидуальные компоненты разложения F
могут быть получены через доступ к свойствам:
F.Q
: ортогональная/унитарная матрицаQ
F.R
: верхняя треугольная матрицаR
F.p
: вектор перестановки пивота (QRPivoted
только)F.P
: матрица перестановки пивота (QRPivoted
только)
Каждая ссылка на верхнюю треугольную фактор через F.R
выделяет новый массив. Поэтому рекомендуется кэшировать этот массив, например, с помощью R = F.R
и продолжать работать с R
.
Итерация разложения производит компоненты Q
, R
, и если существует, p
.
Следующие функции доступны для объектов QR
: inv
, size
, и \
. Когда A
является прямоугольной, \
вернет решение наименьших квадратов, и если решение не уникально, будет возвращено решение с наименьшей нормой. Когда A
не полного ранга, требуется разложение с (колонным) пивотом для получения решения с минимальной нормой.
Умножение относительно полной/квадратной или неполной/квадратной Q
разрешено, т.е. поддерживаются как F.Q*F.R
, так и F.Q*A
. Матрицу Q
можно преобразовать в обычную матрицу с помощью Matrix
. Эта операция возвращает "тонкий" Q-фактор, т.е. если A
имеет размер m
×n
с m>=n
, то Matrix(F.Q)
дает матрицу размером m
×n
с ортонормированными столбцами. Чтобы получить "полный" Q-фактор, ортогональную матрицу размером m
×m
, используйте F.Q*I
или collect(F.Q)
. Если m<=n
, то Matrix(F.Q)
дает ортогональную матрицу размером m
×m
.
Размер блока для QR-разложения можно указать с помощью аргумента blocksize :: Integer
, когда pivot == NoPivot()
и A isa StridedMatrix{<:BlasFloat}
. Он игнорируется, когда blocksize > minimum(size(A))
. См. QRCompactWY
.
Аргумент ключевого слова blocksize
требует Julia 1.4 или более поздней версии.
Примеры
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}}
Q фактор: 3×3 LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}, Matrix{Float64}}
R фактор:
2×2 Matrix{Float64}:
-5.0 10.0
0.0 -1.0
julia> F.Q * F.R == A
true
qr
возвращает несколько типов, потому что LAPACK использует несколько представлений, которые минимизируют требования к памяти для хранения произведений элементарных отражателей Хаусхолдера, так что матрицы Q
и R
могут храниться компактно, а не как две отдельные плотные матрицы.
Noteworthy External Sparse Packages
Несколько других пакетов Julia предоставляют реализации разреженных матриц, которые следует упомянуть:
- SuiteSparseGraphBLAS.jl является оберткой над быстрой многопоточной библиотекой C SuiteSparse:GraphBLAS. На ЦП это обычно самый быстрый вариант, часто значительно превосходящий MKLSparse.
- CUDA.jl предоставляет библиотеку CUSPARSE для операций с разреженными матрицами на GPU.
- SparseMatricesCSR.jl предоставляет нативную реализацию формата сжатых разреженных строк (CSR) на языке Julia.
- MKLSparse.jl ускоряет операции с разреженными и плотными матрицами SparseArrays с использованием библиотеки Intel MKL.
- SparseArrayKit.jl доступен для многомерных разреженных массивов.
- LuxurySparse.jl предоставляет статические разреженные форматы массивов, а также координатный формат.
- ExtendableSparse.jl позволяет быстро вставлять данные в разреженные матрицы, используя ленивый подход к новым хранимым индексам.
- Finch.jl поддерживает обширные форматы и операции с разреженными многомерными массивами через мини-язык тензоров и компилятор, все на нативном Julia. Поддержка COO, CSF, CSR, CSC и других, а также операции, такие как трансляция, редукция и т.д., и пользовательские операции.
Внешние пакеты, предоставляющие разреженные прямые решатели:
Внешние пакеты, предоставляющие решатели для итеративного решения собственных систем и разложений сингулярных значений:
Внешние пакеты для работы с графами:
- ACM887Chen, Y., Davis, T. A., Hager, W. W., & Rajamanickam, S. (2008). Algorithm 887: CHOLMOD, Supernodal Sparse Cholesky Factorization and Update/Downdate. ACM Trans. Math. Softw., 35(3). doi:10.1145/1391989.1391995
- DavisHager2009Davis, Timothy A., & Hager, W. W. (2009). Dynamic Supernodes in Sparse Cholesky Update/Downdate and Triangular Solves. ACM Trans. Math. Softw., 35(4). doi:10.1145/1462173.1462176
- ACM832Дэвис, Тимоти А. (2004b). Алгоритм 832: UMFPACK V4.3–-метод многогранного разложения с нессиметричной структурой. ACM Trans. Math. Softw., 30(2), 196–199. doi:10.1145/992200.992206
- ACM933Foster, L. V., & Davis, T. A. (2013). Algorithm 933: Reliable Calculation of Numerical Rank, Null Space Bases, Pseudoinverse Solutions, and Basic Solutions Using SuitesparseQR. ACM Trans. Math. Softw., 40(1). doi:10.1145/2513109.2513116