Справка по API контейнеров
#
JuMP.Containers — Module
Containers
Модуль, в котором определены контейнеры DenseAxisArray и SparseAxisArray, подобные обычным массивам AbstractArray, но с пользовательскими индексами, которые не обязательно являются целыми числами.
#
JuMP.Containers.AutoContainerType — Type
AutoContainerType
Передайте AutoContainerType в container, чтобы тип контейнера выбирался на основе типа индексов с использованием default_container.
#
JuMP.Containers.DenseAxisArray — Method
DenseAxisArray(data::Array{T, N}, axes...) where {T, N}
Создает массив JuMP с базовыми данными, указанными в массиве data, и заданными осями. Необходимо передать ровно N осей, а их длины должны соответствовать size(data) в соответствующих измерениях.
Пример
julia> array = Containers.DenseAxisArray([1 2; 3 4], [:a, :b], 2:3)
2-dimensional DenseAxisArray{Int64,2,...} with index sets:
Dimension 1, [:a, :b]
Dimension 2, 2:3
And data, a 2×2 Matrix{Int64}:
1 2
3 4
julia> array[:b, 3]
4
#
JuMP.Containers.DenseAxisArray — Method
DenseAxisArray{T}(undef, axes...) where T
Создает неинициализированный массив DenseAxisArray с типом элементов T, индексируемый по заданным осям.
Пример
julia> array = Containers.DenseAxisArray{Float64}(undef, [:a, :b], 1:2);
julia> fill!(array, 1.0)
2-dimensional DenseAxisArray{Float64,2,...} with index sets:
Dimension 1, [:a, :b]
Dimension 2, 1:2
And data, a 2×2 Matrix{Float64}:
1.0 1.0
1.0 1.0
julia> array[:a, 2] = 5.0
5.0
julia> array[:a, 2]
5.0
julia> array
2-dimensional DenseAxisArray{Float64,2,...} with index sets:
Dimension 1, [:a, :b]
Dimension 2, 1:2
And data, a 2×2 Matrix{Float64}:
1.0 5.0
1.0 1.0
#
JuMP.Containers.DenseAxisArrayKey — Type
DenseAxisArrayKey
Структура для хранения ключа DenseAxisArray, когда он рассматривается как коллекция ключей и значений.
#
JuMP.Containers.NestedIterator — Type
struct NestedIterator{T}
iterators::T # Tuple of functions
condition::Function
end
Итераторы по кортежам, создаваемым вложенным циклом for.
Итератор NestedIterator создается с помощью nested.
Пример
julia> iterators = (() -> 1:2, (i,) -> ["A", "B"]);
julia> condition = (i, j) -> isodd(i) || j == "B";
julia> x = Containers.NestedIterator(iterators, condition);
julia> for (i, j) in x
println((i, j))
end
(1, "A")
(1, "B")
(2, "B")
равносильно
julia> for i in iterators[1]()
for j in iterators[2](i)
if condition(i, j)
println((i, j))
end
end
end
(1, "A")
(1, "B")
(2, "B")
#
JuMP.Containers.NoDuplicateDict — Type
struct NoDuplicateDict{K, V} <: AbstractDict{K, V}
dict::OrderedCollections.OrderedDict{K, V}
end
Действует аналогично OrderedCollections.OrderedDict{K, V}, но выдает ошибку при создании на основе итератора с повторяющимися ключами.
#
JuMP.Containers.SparseAxisArray — Type
struct SparseAxisArray{T,N,K<:NTuple{N, Any}} <: AbstractArray{T,N}
data::OrderedCollections.OrderedDict{K,T}
end
N-мерный массив с элементами типа T, в котором определено лишь подмножество элементов. Элементы с индексами idx = (i1, i2, ..., iN) в keys(data) имеют значение data[idx].
Обратите внимание, что, в отличие от SparseArrays.AbstractSparseArray, отсутствующие элементы не считаются zero(T); они просто не входят в массив. Это означает, что результат вызова map(f, sa::SparseAxisArray) или f.(sa::SparseAxisArray) имеет ту же структуру разреженности, что и sa, даже если f(zero(T)) не равно нулю.
Пример
julia> using OrderedCollections: OrderedDict
julia> dict = OrderedDict((:a, 2) => 1.0, (:a, 3) => 2.0, (:b, 3) => 3.0)
OrderedDict{Tuple{Symbol, Int64}, Float64} with 3 entries:
(:a, 2) => 1.0
(:a, 3) => 2.0
(:b, 3) => 3.0
julia> array = Containers.SparseAxisArray(dict)
SparseAxisArray{Float64, 2, Tuple{Symbol, Int64}} with 3 entries:
[a, 2] = 1.0
[a, 3] = 2.0
[b, 3] = 3.0
julia> array[:b, 3]
3.0
#
JuMP.Containers.VectorizedProductIterator — Type
struct VectorizedProductIterator{T}
prod::Iterators.ProductIterator{T}
end
Тип-оболочка для Iterators.ProuctIterator, который игнорирует информацию о форме и возвращает Vector.
Итератор VectorizedProductIterator создается с помощью vectorized_product.
#
JuMP.Containers._explicit_oneto — _Method
_explicit_oneto(error_fn, index_set)
Если index_set соответствует форме 1:N, возвращается Base.OneTo(index_set).
#
JuMP.Containers._expr_is_splat — _Method
_expr_is_splat(expr)
Возвращает значение true, если expr — это выражение ... (или esc).
#
JuMP.Containers._extract_kw_args — _Method
_extract_kw_args(args)
|
Эта функция является нерекомендуемой. Используйте вместо нее |
#
JuMP.Containers._get_arg — _Method
_get_arg(args::Tuple, index::Tuple)
Возвращает кортеж, который соответствует tuple([arg[index] for arg in args]...), но стабилен по типу.
#
JuMP.Containers._parse_ref_sets — _Method
_parse_ref_sets(expr::Expr)
Вспомогательная функция для макросов, позволяющая создавать объекты-контейнеры.
Принимает выражение Expr, которое определяет контейнер, например :(x[i=1:3,[:red,:blue],k=S; i+k <= 6]), и возвращает следующие значения:
-
index_vars: имена переменных индексов, например[:i, gensym(), :k].
Это также могут быть выражения, например :i, j из такого вызова, как :(x[(i, j) in S]).
-
index_sets: множества, используемые для индексирования, например[1:3, [:red,:blue], S]. -
condition: выражение, содержащее все условия, налагаемые на индексирование, или:(),
если таковых нет.
#
JuMP.Containers.add_additional_args — Method
add_additional_args(
call::Expr,
args::Vector,
kwargs::Dict{Symbol,Any};
kwarg_exclude::Vector{Symbol} = Symbol[],
)
Добавляет позиционные аргументы args в выражение вызова функции call, экранируя каждое выражение аргумента.
Эта функция может включать дополнительные позиционные аргументы для вызовов call, которые уже содержат именованные аргументы.
#
JuMP.Containers.build_error_fn — Method
build_error_fn(macro_name, args, source)
Возвращает функцию, которую можно использовать вместо Base.error, но которая дополнительно выводит макрос, из которого она была вызвана.
#
JuMP.Containers.build_name_expr — Method
build_name_expr(
name::Union{Symbol,Nothing},
index_vars::Vector,
kwargs::Dict{Symbol,Any},
)
Возвращает выражение для имени элемента контейнера, где name и index_vars — значения, возвращаемые parse_ref_sets, а kwargs — словарь, возвращаемый parse_macro_arguments.
Предполагается, что ключ в kwargs, используемый для переопределения выбранного имени, — это :base_name.
Пример
julia> Containers.build_name_expr(:x, [:i, :j], Dict{Symbol,Any}())
:(string("x", "[", string($(Expr(:escape, :i))), ",", string($(Expr(:escape, :j))), "]"))
julia> Containers.build_name_expr(nothing, [:i, :j], Dict{Symbol,Any}())
""
julia> Containers.build_name_expr(:y, [:i, :j], Dict{Symbol,Any}(:base_name => "y"))
:(string("y", "[", string($(Expr(:escape, :i))), ",", string($(Expr(:escape, :j))), "]"))
#
JuMP.Containers.build_ref_sets — Method
build_ref_sets(error_fn::Function, expr)
Эта функция является нерекомендуемой. Используйте вместо нее parse_ref_sets.
#
JuMP.Containers.container — Method
container(f::Function, indices[[, ::Type{C} = AutoContainerType], names])
Создает контейнер типа C с именами индексов names, индексами indices и значениями по индексам, определяемыми функцией f.
Если метод с names не специализирован для Type{C}, по умолчанию вызывается container(f, indices, c) для обратной совместимости с контейнерами, не поддерживающими имена индексов.
Пример
julia> Containers.container((i, j) -> i + j, Containers.vectorized_product(Base.OneTo(3), Base.OneTo(3)))
3×3 Matrix{Int64}:
2 3 4
3 4 5
4 5 6
julia> Containers.container((i, j) -> i + j, Containers.vectorized_product(1:3, 1:3))
2-dimensional DenseAxisArray{Int64,2,...} with index sets:
Dimension 1, 1:3
Dimension 2, 1:3
And data, a 3×3 Matrix{Int64}:
2 3 4
3 4 5
4 5 6
julia> Containers.container((i, j) -> i + j, Containers.vectorized_product(2:3, Base.OneTo(3)))
2-dimensional DenseAxisArray{Int64,2,...} with index sets:
Dimension 1, 2:3
Dimension 2, Base.OneTo(3)
And data, a 2×3 Matrix{Int64}:
3 4 5
4 5 6
julia> Containers.container((i, j) -> i + j, Containers.nested(() -> 1:3, i -> i:3, condition = (i, j) -> isodd(i) || isodd(j)))
SparseAxisArray{Int64, 2, Tuple{Int64, Int64}} with 5 entries:
[1, 1] = 2
[1, 2] = 3
[1, 3] = 4
[2, 3] = 5
[3, 3] = 6
#
JuMP.Containers.container_code — Method
container_code(
index_vars::Vector{Any},
indices::Expr,
code,
requested_container::Union{Symbol,Expr,Dict{Symbol,Any}},
)
Используется в макросах для построения вызова container. Следует использовать в сочетании с parse_ref_sets.
Аргументы
-
index_vars::Vector{Any}: вектор имен индексов контейнера. Это также могут быть выражения, например:i, jиз такого вызова, как:(x[(i, j) in S]). -
indices::Expr: выражение, результатом вычисления которого является итератор индексов. -
code: выражение или литеральная константа для значения, которое будет сохранено в контейнере как функция именованногоindex_vars. -
requested_container: передается в третьем аргументеcontainer. Для встроенных типов JuMP выберите:Array,:DenseAxisArray,:SparseAxisArrayили:Auto. Для пользовательского контейнера результат вычисления этого выражения должен иметь правильный тип. Можно также передать словарьkwargsизparse_macro_arguments.
|
В большинстве случаев перед передачей кода в |
Пример
julia> macro foo(ref_sets, code)
name, index_vars, indices =
Containers.parse_ref_sets(error, ref_sets)
@assert name !== nothing # Анонимный контейнер не поддерживается
container =
Containers.container_code(index_vars, indices, esc(code), :Auto)
return quote
$(esc(name)) = $container
end
end
@foo (macro with 1 method)
julia> @foo(x[i=1:2, j=["A", "B"]], j^i);
julia> x
2-dimensional DenseAxisArray{String,2,...} with index sets:
Dimension 1, Base.OneTo(2)
Dimension 2, ["A", "B"]
And data, a 2×2 Matrix{String}:
"A" "B"
"AA" "BB"
#
JuMP.Containers.default_container — Function
default_container(indices)
Если indices — это объект NestedIterator, возвращает SparseAxisArray. В противном случае indices должно быть объектом VectorizedProductIterator, и эта функция возвращает Array, если все итераторы произведения равны Base.OneTo, или DenseAxisArray в противном случае.
#
JuMP.Containers.nested — Method
nested(iterators...; condition = (args...) -> true)
Создает объект NestedIterator.
Пример
julia> iterator = Containers.nested(
() -> 1:2,
(i,) -> ["A", "B"];
condition = (i, j) -> isodd(i) || j == "B",
);
julia> collect(iterator)
3-element Vector{Tuple{Int64, String}}:
(1, "A")
(1, "B")
(2, "B")
#
JuMP.Containers.parse_macro_arguments — Method
parse_macro_arguments(
error_fn::Function,
args;
valid_kwargs::Union{Nothing,Vector{Symbol}} = nothing,
num_positional_args::Union{Nothing,Int,UnitRange{Int}} = nothing,
)
Возвращает кортеж Tuple{Vector{Any},Dict{Symbol,Any}}, содержащий упорядоченные позиционные аргументы и словарь, в котором сопоставляются именованные аргументы.
В частности, служит для различения @foo(key = value) и @foo(; key = value) в макросах.
При передаче нескольких именованных аргументов с одинаковым ключом выдается ошибка.
Если valid_kwargs — это объект Vector{Symbol}, при отсутствии именованного аргумента в valid_kwargs выдается ошибка.
Если значение num_positional_args отлично от nothing, при отсутствии числа позиционных аргументов в num_positional_args выдается ошибка.
#
JuMP.Containers.parse_ref_sets — Method
parse_ref_sets(
error_fn::Function,
expr;
invalid_index_variables::Vector{Symbol} = Symbol[],
)
Вспомогательная функция для макросов, позволяющая создавать объекты-контейнеры.
|
Эта функция предназначена для опытных пользователей, реализующих расширения JuMP. Дополнительные сведения см. в описании метода |
Аргументы
-
error_fn: функция, которая принимаетStringи выдает ошибку; входная строка может быть аннотирована дополнительной информацией, например именем макроса, из которого была выдана ошибка. Чтобы не изменять сообщение об ошибке, используйтеerror. -
expr: выражениеExpr, которое определяет контейнер, например:(x[i = 1:3, [:red, :blue], k = S; i + k <= 6]).
Возвращаемые значения
-
name: имя контейнера, если оно задано; в противном случаеnothing. -
index_vars: векторVector{Any}имен переменных индексов, например
[:i, gensym(), :k]. Это также могут быть выражения, например :i, j из такого вызова, как :(x[(i, j) in S]).
-
indices: итератор по индексам, например
Пример
Рабочий пример см. в описании метода container_code.
#
JuMP.Containers.rowtable — Method
rowtable([f::Function=identity,] x; [header::Vector{Symbol} = Symbol[]])
Применяет функцию f ко всем элементам контейнера переменных x, возвращая результат в виде вектора Vector кортежей NamedTuple, где header — это вектор с соответствующими именами осей.
Если x — это N-мерный массив, то имен должно быть N+1, чтобы последнее имя соответствовало результату f(x[i]).
Если аргумент header пустой, то заголовок по умолчанию будет [:x1, :x2, ..., :xN, :y].
|
Вектор |
Пример
julia> model = Model();
julia> @variable(model, x[i=1:2, j=i:2] >= 0, start = i+j);
julia> Containers.rowtable(start_value, x; header = [:i, :j, :start])
3-element Vector{@NamedTuple{i::Int64, j::Int64, start::Float64}}:
(i = 1, j = 1, start = 2.0)
(i = 1, j = 2, start = 3.0)
(i = 2, j = 2, start = 4.0)
julia> Containers.rowtable(x)
3-element Vector{@NamedTuple{x1::Int64, x2::Int64, y::VariableRef}}:
(x1 = 1, x2 = 1, y = x[1,1])
(x1 = 1, x2 = 2, y = x[1,2])
(x1 = 2, x2 = 2, y = x[2,2])
#
JuMP.Containers.vectorized_product — Method
vectorized_product(iterators...)
Создает объект VectorizedProductIterator.
Пример
julia> iterator = Containers.vectorized_product(1:2, ["A", "B"]);
julia> collect(iterator)
2×2 Matrix{Tuple{Int64, String}}:
(1, "A") (1, "B")
(2, "A") (2, "B")
#
JuMP.Containers.@container — Macro
@container([i=..., j=..., ...], expr[, container = :Auto])
Создает контейнер с индексами i, j, … и значениями, задаваемыми выражением expr, которые могут зависеть от значения индексов.
@container(ref[i=..., j=..., ...], expr[, container = :Auto])
То же, что и выше, но контейнер присваивается переменной с именем ref.
Типом контейнера можно управлять с помощью именованного аргумента container.
|
Когда множество индексов явно задано как |
Пример
julia> Containers.@container([i = 1:3, j = 1:3], i + j)
3×3 Matrix{Int64}:
2 3 4
3 4 5
4 5 6
julia> I = 1:3
1:3
julia> Containers.@container(x[i = I, j = I], i + j);
julia> x
2-dimensional DenseAxisArray{Int64,2,...} with index sets:
Dimension 1, 1:3
Dimension 2, 1:3
And data, a 3×3 Matrix{Int64}:
2 3 4
3 4 5
4 5 6
julia> Containers.@container([i = 2:3, j = 1:3], i + j)
2-dimensional DenseAxisArray{Int64,2,...} with index sets:
Dimension 1, 2:3
Dimension 2, Base.OneTo(3)
And data, a 2×3 Matrix{Int64}:
3 4 5
4 5 6
julia> Containers.@container([i = 1:3, j = 1:3; i <= j], i + j)
SparseAxisArray{Int64, 2, Tuple{Int64, Int64}} with 6 entries:
[1, 1] = 2
[1, 2] = 3
[1, 3] = 4
[2, 2] = 4
[2, 3] = 5
[3, 3] = 6