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))
trueSparse 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.0sparse(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 ⋅
⋅ ⋅ 3SparseArrays.sparse! — Functionsparse!(I::AbstractVector{Ti}, J::AbstractVector{Ti}, V::AbstractVector{Tv},
m::Integer, n::Integer, combine, klasttouch::Vector{Ti},
csrrowptr::Vector{Ti}, csrcolval::Vector{Ti}, csrnzval::Vector{Tv},
[csccolptr::Vector{Ti}], [cscrowval::Vector{Ti}, cscnzval::Vector{Tv}] ) where {Tv,Ti<:Integer}Родитель и экспертный драйвер для 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] = 1sparsevec(d::Dict, [m])Создает разреженный вектор длины m, где ненулевые индексы являются ключами из словаря, а ненулевые значения — значениями из словаря.
Примеры
julia> sparsevec(Dict(1 => 3, 2 => 2))
2-element SparseVector{Int64, Int64} with 2 stored entries:
[1] = 3
[2] = 2sparsevec(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.0Base.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))
falseSparseArrays.nnz — Functionnnz(A)Возвращает количество хранимых (заполненных) элементов в разреженном массиве.
Примеры
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} с 3 хранимыми записями:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> nnz(A)
3SparseArrays.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 ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ 3SparseArrays.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 ⋅
⋅ ⋅ ⋅ ⋅ 4SparseArrays.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.49425SparseArrays.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.234641SparseArrays.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
2SparseArrays.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
3SparseArrays.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.0dropzeros(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.0SparseArrays.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
truecholesky(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
truecholesky(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.3488372093023255ldlt(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.0LinearAlgebra.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
2qr(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: ортогональная/унитарная матрицаQF.R: верхняя треугольная матрицаRF.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
trueqr возвращает несколько типов, потому что 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