Разреженные массивы
Julia поддерживает разреженные векторы и разреженные матрицы в модуле SparseArrays stdlib. Разреженные массивы — это массивы, содержащие достаточно нулей, что хранение их в специальной структуре данных приводит к экономии памяти и времени выполнения по сравнению с плотным массивом.
Внешние пакеты, которые реализуют различные типы разреженного хранения, многомерные разреженные массивы и многое другое, можно найти в Важных внешних пакетах разреженных массивов
Хранение разреженной матрицы в формате Compressed Sparse Column (CSC)
В Julia разреженные матрицы хранятся в формате Compressed Sparse Column (CSC). Разреженные матрицы 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 для повышения производительности и для избежания дорогостоящих операций.
Если у вас есть данные в формате 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 ⋅
⋅ ⋅ ⋅
Хранение разреженных векторов
Разреженные векторы хранятся в аналоге сжатого столбца (CSC) для разреженных матриц. В 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 также может содержать явно хранимые нули. (См. Хранение разреженной матрицы.)
Конструкторы разреженных векторов и матриц
Самый простой способ создать разреженный массив — использовать функцию, эквивалентную функции zeros, которую предоставляет Julia для работы с плотными массивами. Чтобы вместо этого создать разреженный массив, можно использовать то же имя с префиксом sp:
julia> spzeros(3)
3-element SparseVector{Float64, Int64} with 0 stored entries
Функция sparse часто является удобным способом создания разреженных массивов. Например, чтобы создать разреженную матрицу, мы можем ввести вектор I индексов строк, вектор J индексов столбцов и вектор V хранимых значений (это также известно как формат COO (координат)). 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
Операции с разреженными матрицами
Арифметические операции над разреженными матрицами также работают так же, как и над плотными матрицами. Индексирование, присваивание и конкатенация разреженных матриц работают так же, как и плотных матриц. Операции индексирования, особенно присваивание, являются дорогостоящими, когда выполняются по одному элементу за раз. Во многих случаях может быть лучше преобразовать разреженную матрицу в формат (I,J,V) с помощью findnz, обработать значения или структуру в плотных векторах (I,J,V), а затем восстановить разреженную матрицу.
Соответствие плотных и разреженных методов
В следующей таблице приведено соответствие встроенных методов для разреженных матриц и соответствующих методов для плотных типов матриц. В общем случае методы, генерирующие разреженные матрицы, отличаются от своих плотных аналогов тем, что полученная матрица следует той же схеме разреженности, что и заданная разреженная матрица S, или что полученная разреженная матрица имеет плотность d, т.е. каждый элемент матрицы имеет вероятность d быть ненулевым.
Подробные сведения можно найти в разделе «Разреженные векторы и матрицы» справочника стандартной библиотеки.
| Разреженный | Плотнoй | Описание |
|---|---|---|
spzeros(m,n) |
zeros(m,n) |
Создаёт m-на-n матрицу нулей. (spzeros(m,n) пуста.) |
sparse(I,n,n) |
Matrix(I,n,n) |
Создаёт n-на-n единичную матрицу. |
sparse(A) |
Array(S) |
Переводит между плотными и разреженными форматами. |
sprand(m,n,d) |
rand(m,n) |
Создаёт случайную m-на-n матрицу (плотности d) с независимыми и одинаково распределёнными ненулевыми элементами, равномерно распределёнными на полуоткрытом интервале $[0, 1)$. |
sprandn(m,n,d) |
randn(m,n) |
Создаёт случайную m-на-n матрицу (плотности d) с независимыми и одинаково распределёнными ненулевыми элементами, распределёнными по стандартному нормальному (гауссовому) распределению. |
sprandn(rng,m,n,d) |
randn(rng,m,n) |
Создаёт случайную m-на-n матрицу (плотности d) с независимыми и одинаково распределёнными ненулевыми элементами, сгенерированными с помощью rng генератора случайных чисел |
Разрешённая линейная алгебра
Решатели разреженных матриц вызывают функции из SuiteSparse. Доступны следующие факторизации:
| Тип | Описание |
|---|---|
CHOLMOD.Factor |
Факторизации Холецкого и LDLt |
UMFPACK.UmfpackLU |
Факторизация LU |
SPQR.QRSparse |
Факторизация QR |
Эти факторизации описаны более подробно в разделе API разрешённой линейной алгебры:
API SparseArrays
SparseArrays.AbstractSparseArrayТип
AbstractSparseArray{Tv,Ti,N}
Надтип для N-мерных разреженных массивов (или похожих на массивы типов) с элементами типа Tv и типом индекса Ti. SparseMatrixCSC, SparseVector и SuiteSparse.CHOLMOD.Sparse являются подтипами этого.
SparseArrays.AbstractSparseVectorТип
AbstractSparseVector{Tv,Ti}
Надтип для одномерных разреженных массивов (или похожих на массивы типов) с элементами типа Tv и типом индекса Ti. Псевдоним для AbstractSparseArray{Tv,Ti,1}.
SparseArrays.AbstractSparseMatrixТип
AbstractSparseMatrix{Tv,Ti}
Надтип для двумерных разреженных массивов (или похожих на массивы типов) с элементами типа Tv и типом индекса Ti. Псевдоним для AbstractSparseArray{Tv,Ti,2}.
SparseArrays.SparseVectorТип
SparseVector{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Тип
SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}
Тип матрицы для хранения разреженных матриц в формате Сжатых столбцов. Стандартный способ создания SparseMatrixCSC — через функцию sparse. Также см. spzeros, spdiagm и sprand.
SparseArrays.sparseФункция
sparse(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 не задана, combine по умолчанию равно +, если элементы V не являются булевыми значениями, в противном случае combine по умолчанию равно |. Все элементы 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} with 3 stored entries:
1 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 3
SparseArrays.sparse!Функция
sparse!(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, "Two fast algorithms for sparse matrices: multiplication and permuted transposition," 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 хранит, и они будут resize!d по мере необходимости.
Обратите внимание, что некоторые буферы работы все еще будут выделены. В частности, этот метод является удобной оболочкой вокруг 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Функция
sparsevec(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.0
Base.similarМетод
similar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}
Создать неинициализированный изменяемый массив с заданным типом элементов, типом индекса и размером, основанным на заданном источнике SparseMatrixCSC. Новая разреженная матрица сохраняет структуру исходной разреженной матрицы, за исключением случая, когда размеры выходной матрицы отличаются от выходной.
Выходная матрица имеет нули в тех же местах, что и входная, но неинициализированные значения для ненулевых позиций.
SparseArrays.issparseФункция
issparse(S)
Возвращает true если S является разреженным, и false в противном случае.
Примеры
julia> sv = sparsevec([1, 4], [2.3, 2.2], 10)
10-element SparseVector{Float64, Int64} with 2 stored entries:
[1] = 2.3
[4] = 2.2
julia> issparse(sv)
true
julia> issparse(Array(sv))
false
SparseArrays.nnzФункция
nnz(A)
Возвращает количество хранимых (заполненных) элементов в разреженном массиве.
Примеры
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> nnz(A)
3
SparseArrays.findnzФункция
findnz(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} with 4 stored entries:
1 2 ⋅
⋅ ⋅ 3
⋅ 4 ⋅
julia> findnz(A)
([1, 1, 3, 2], [1, 2, 2, 3], [1, 2, 4, 3])
SparseArrays.spzerosФункция
spzeros([type,]m[,n])
Создайте разреженный вектор длины m или разреженную матрицу размера m x n. Этот разреженный массив не будет содержать ненулевых значений. Во время создания не будет выделено памяти для ненулевых значений. Тип по умолчанию — Float64, если не указан другой.
Примеры
julia> spzeros(3, 3)
3×3 SparseMatrixCSC{Float64, Int64} with 0 stored entries:
⋅ ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ ⋅
julia> spzeros(Float32, 4)
4-element SparseVector{Float32, Int64} with 0 stored entriesspzeros([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!Функция
spzeros!(::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Функция
spdiagm(kv::Pair{<:Integer,<:AbstractVector}...)
spdiagm(m::Integer, n::Integer, kv::Pair{<:Integer,<:AbstractVector}...)
Построение разреженной диагональной матрицы из Pair векторов и диагоналей. Каждый вектор kv.second будет помещён на kv.first диагональ. По умолчанию матрица квадратная, а её размер выводится из kv, но неквадратный размер m×n (дополнен нулями по мере необходимости) может быть указан путём передачи m,n в качестве первых аргументов.
Примеры
julia> spdiagm(-1 => [1,2,3,4], 1 => [4,3,2,1])
5×5 SparseMatrixCSC{Int64, Int64} with 8 stored entries:
⋅ 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Функция
sparse_hcat(A...)
Конкатенация по размерности 2. Возвращает объект SparseMatrixCSC.
Этот метод был добавлен в Julia 1.8. Он имитирует предыдущее поведение конкатенации, где конкатенация со специализированными типами «разреженных» матриц из LinearAlgebra.jl автоматически возвращала разреженный результат даже при отсутствии какого-либо аргумента SparseArray.
SparseArrays.sparse_vcatФункция
sparse_vcat(A...)
Конкатенация по размерности 1. Возвращает объект SparseMatrixCSC.
Этот метод был добавлен в Julia 1.8. Он имитирует предыдущее поведение конкатенации, где конкатенация со специализированными типами «разреженных» матриц из LinearAlgebra.jl автоматически возвращала разреженный результат даже при отсутствии какого-либо аргумента SparseArray.
SparseArrays.sparse_hvcatФункция
sparse_hvcat(rows::Tuple{Vararg{Int}}, values...)
Разреженная горизонтальная и вертикальная конкатенация в одном вызове. Эта функция вызывается для синтаксиса блочной матрицы. Первый аргумент определяет количество аргументов для конкатенации в каждом блочном ряду.
Этот метод был добавлен в Julia 1.8. Он имитирует предыдущее поведение конкатенации, где конкатенация со специализированными типами «разреженных» матриц из LinearAlgebra.jl автоматически возвращала разреженный результат даже при отсутствии какого-либо аргумента SparseArray.
SparseArrays.blockdiagФункция
blockdiag(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Функция
sprand([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} with 2 stored entries:
1 1
⋅ ⋅
julia> sprand(Float64, 3, 0.75)
3-element SparseVector{Float64, Int64} with 2 stored entries:
[1] = 0.795547
[2] = 0.49425
SparseArrays.sprandnФункция
sprandn([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Функция
nonzeros(A)
Возвращает вектор структурных ненулевых значений в разреженном массиве A. Это включает нули, которые явным образом хранятся в разреженном массиве. Возвращаемый вектор напрямую ссылается на внутреннее хранилище ненулевых значений A, и любые изменения в возвращаемом векторе изменят также A. См. rowvals и nzrange.
Примеры
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> nonzeros(A)
3-element Vector{Int64}:
2
2
2
SparseArrays.rowvalsФункция
rowvals(A::AbstractSparseMatrixCSC)
Возвращает вектор индексов строк A. Любые изменения в возвращаемом векторе изменят также A. Предоставление доступа к тому, как хранятся индексы строк, может быть полезно в сочетании с итерацией по структурно ненулевым значениям. См. также nonzeros и nzrange.
Примеры
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> rowvals(A)
3-element Vector{Int64}:
1
2
3
SparseArrays.nzrangeФункция
nzrange(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]
# perform sparse wizardry...
end
end
Добавление или удаление ненулевых элементов в матрицу может привести к недействительности nzrange, поэтому не следует изменять матрицу во время итерации.
nzrange(x::SparseVectorUnion, col)
Указывает диапазон индексов ненулевых структурных значений разреженного вектора. Индекс столбца col игнорируется (предполагается, что он 1).
SparseArrays.droptol!Функция
droptol!(A::AbstractSparseMatrixCSC, tol)
Удаляет сохранённые значения из A, модуль которых меньше или равен tol.
droptol!(x::AbstractCompressedVector, tol)
Удаляет сохранённые значения из x, модуль которых меньше или равен tol.
SparseArrays.dropzeros!Функция
dropzeros!(x::AbstractCompressedVector)
Удаляет сохранённые числовые нули из x.
Для варианта вне места, см. dropzeros. Для информации об алгоритме, см. fkeep!.
SparseArrays.dropzerosФункция
dropzeros(A::AbstractSparseMatrixCSC;)
Создаёт копию A и удаляет из неё сохранённые числовые нули.
Для версии в формате «на месте» и алгоритмической информации см. dropzeros!.
Примеры
julia> A = sparse([1, 2, 3], [1, 2, 3], [1.0, 0.0, 1.0])
3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
1.0 ⋅ ⋅
⋅ 0.0 ⋅
⋅ ⋅ 1.0
julia> dropzeros(A)
3×3 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
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.0
SparseArrays.permuteФункция
permute(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!Метод
permute!(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!Функция
halfperm!(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, описанный в работе Ф. Густавсона «Два быстрых алгоритма для разреженных матриц: умножение и переставленное транспонирование», ACM TOMS 4(3), 250-269 (1978). Алгоритм работает за время O(size(A, 1), size(A, 2), nnz(A)) и не требует памяти, превышающей ту, что передана в качестве аргумента.
SparseArrays.ftranspose!Функция
ftranspose!(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!
API разреженной линейной алгебры
LinearAlgebra.choleskyФункция
cholesky(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 factor:
3×3 UpperTriangular{Float64, Matrix{Float64}}:
2.0 6.0 -8.0
⋅ 1.0 5.0
⋅ ⋅ 3.0
julia> C.U
3×3 UpperTriangular{Float64, Matrix{Float64}}:
2.0 6.0 -8.0
⋅ 1.0 5.0
⋅ ⋅ 3.0
julia> C.L
3×3 LowerTriangular{Float64, Matrix{Float64}}:
2.0 ⋅ ⋅
6.0 1.0 ⋅
-8.0 5.0 3.0
julia> C.L * C.U == A
truecholesky(A, RowMaximum(); tol = 0.0, check = true) -> 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 factor with rank 1:
4×4 UpperTriangular{Float64, Matrix{Float64}}:
4.0 2.0 3.0 1.0
⋅ 0.0 6.0 2.0
⋅ ⋅ 9.0 3.0
⋅ ⋅ ⋅ 1.0
permutation:
4-element Vector{Int64}:
4
2
3
1
julia> C.U[1:C.rank, :]' * C.U[1:C.rank, :] ≈ A[C.p, C.p]
true
julia> l, u = C; # destructuring via iteration
julia> l == C.L && u == C.U
truecholesky(A::SparseMatrixCSC; shift = 0.0, check = true, perm = nothing) -> CHOLMOD.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), задающей порядок (вместо по умолчанию используемой в CHOLMOD перестановки AMD).
Примеры
В следующем примере используемая перестановка, сокращающая заполнение, равна [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!Функция
cholesky!(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Функция
lowrankupdate(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.
Возвращаемый фактор всегда является разложением Холецкого.
См. также lowrankupdate!, lowrankdowndate, lowrankdowndate!.
LinearAlgebra.lowrankupdate!Функция
lowrankupdate!(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)
Обновить разложение Холецкого или LLt F матрицы A на разложение матрицы A + C*C'.
Разложения Холецкого конвертируются в LDLt.
См. также lowrankupdate, lowrankdowndate, lowrankdowndate!.
LinearAlgebra.lowrankdowndateФункция
lowrankdowndate(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.
Возвращаемый фактор всегда является разложением Холецкого.
См. также lowrankdowndate!, lowrankupdate, lowrankupdate!.
LinearAlgebra.lowrankdowndate!Функция
lowrankdowndate!(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)
Обновить разложение Холецкого или LLt F матрицы A на разложение матрицы A - C*C'.
Разложения Холецкого конвертируются в LDLt.
См. также lowrankdowndate, lowrankupdate, lowrankupdate!.
SparseArrays.CHOLMOD.lowrankupdowndate!Функция
lowrankupdowndate!(F::CHOLMOD.Factor, C::Sparse, update::Cint)
Обновить разложение Холецкого или 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Функция
ldlt(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Функция
lu(A::AbstractSparseMatrixCSC; check = true, q = nothing, control = get_umfpack_control()) -> F::UmfpackLU
Вычислить LU-факторизацию разреженной матрицы A.
Для разреженной A с вещественным или комплексным типом элементов, тип возвращаемого значения F это UmfpackLU{Tv, Ti}, где Tv = Float64 или ComplexF64 соответственно, и Ti является целым типом (Int32 или Int64).
Если check = true, при неудачном разложении выбрасывается ошибка. Если check = false, ответственность за проверку корректности разложения (через issuccess) лежит на пользователе.
Перестановка q может быть вектором перестановки или nothing. Если вектор перестановки не указан или q это nothing, используется значение по умолчанию UMFPACK. Если перестановка не нулево-базовая, создается нулево-базовая копия.
Вектор control по умолчанию соответствует настройкам по умолчанию пакета Julia SparseArrays для UMFPACK (Примечание: это изменено по сравнению с настройками по умолчанию UMFPACK для отключения итерационной уточнения), но может быть изменён путём передачи вектора длиной UMFPACK_CONTROL, см. руководство UMFPACK для возможных конфигураций. Например, чтобы снова включить итерационную уточнение:
umfpack_control = SparseArrays.UMFPACK.get_umfpack_control(Float64, Int64) # read Julia default configuration for a Float64 sparse matrix SparseArrays.UMFPACK.show_umf_ctrl(umfpack_control) # optional - display values umfpack_control[SparseArrays.UMFPACK.JL_UMFPACK_IRSTEP] = 2.0 # reenable iterative refinement (2 is UMFPACK default max iterative refinement steps) Alu = lu(A; control = umfpack_control) x = Alu \ b # solve Ax = b, including UMFPACK iterative refinement
Отдельные компоненты факторизации 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 factor:
2×2 Matrix{Float64}:
1.0 0.0
0.666667 1.0
U factor:
2×2 Matrix{Float64}:
6.0 3.0
0.0 1.0
julia> F.L * F.U == A[F.p, :]
true
julia> l, u, p = lu(A); # destructuring via iteration
julia> l == F.L && u == F.U && p == F.p
true
julia> lu([1 2; 1 2], allowsingular = true)
LU{Float64, Matrix{Float64}, Vector{Int64}}
L factor:
2×2 Matrix{Float64}:
1.0 0.0
1.0 1.0
U factor (rank-deficient):
2×2 Matrix{Float64}:
1.0 2.0
0.0 0.0
LinearAlgebra.qrФункция
qr(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} with 4 stored entries:
1.0 ⋅
1.0 ⋅
⋅ 1.0
⋅ 1.0
julia> qr(A)
SparseArrays.SPQR.QRSparse{Float64, Int64}
Q factor:
4×4 SparseArrays.SPQR.QRSparseQ{Float64, Int64}
R factor:
2×2 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
-1.41421 ⋅
⋅ -1.41421
Row permutation:
4-element Vector{Int64}:
1
3
4
2
Column permutation:
2-element Vector{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: ортогональная/унитарная матрица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 factor: 3×3 LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}, Matrix{Float64}}
R factor:
2×2 Matrix{Float64}:
-5.0 10.0
0.0 -1.0
julia> F.Q * F.R == A
true
qr возвращает несколько типов, потому что LAPACK использует несколько представлений, которые минимизируют требования к памяти для хранения произведений элементарных отражателей Хаусхолдера, так что матрицы Q и R могут быть компактно хранятся, а не как две отдельные плотные матрицы.
Заслуживающие внимания внешние пакеты разреженных матриц
Несколько других пакетов Julia предоставляют реализации разреженных матриц, которые стоит упомянуть:
SuiteSparseGraphBLAS.jl является обёрткой над быстрой, многопоточной библиотекой SuiteSparse:GraphBLAS на C. На процессоре это, как правило, самый быстрый вариант, часто значительно превосходящий MKLSparse.
CUDA.jl предоставляет библиотеку CUSPARSE для операций с разреженными матрицами на GPU.
SparseMatricesCSR.jl предоставляет собственную реализацию формата Compressed Sparse Rows (CSR) на Julia.
MKLSparse.jl ускоряет операции с разреженными-плоскими матрицами SparseArrays с использованием библиотеки Intel MKL.
SparseArrayKit.jl доступен для многомерных разреженных массивов.
LuxurySparse.jl предоставляет статические форматы разреженных массивов, а также формат координат.
ExtendableSparse.jl обеспечивает быструю вставку в разреженные матрицы, используя отложенный подход к новым индексам хранения.
Finch.jl поддерживает обширные форматы и операции с многомерными разреженными массивами через мини-язык тензоров и компилятор, всё нативно в Julia. Поддержка форматов COO, CSF, CSR, CSC и других, а также операции типа broadcast, reduce и пользовательские операции.
Внешие пакеты, предоставляющие решения для прямого решения систем:
Внешие пакеты, предоставляющие решения для итерационного решения систем собственных значений и сингулярных разложений:
Внешие пакеты для работы с графами:
- 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
- ACM832Davis, Timothy A. (2004b). Algorithm 832: UMFPACK V4.3–-an Unsymmetric-Pattern Multifrontal Method. ACM Trans. Math. Softw., 30(2), 196–199. doi:10.1145/992200.992206
- ACM933Foster, L. V., & Davis, T. A. (2013). 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
© 2009–2024 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v1.11/stdlib/SparseArrays/