Skip to content

Commit 936e475

Browse files
authored
Add value_type for AbstractFunction (#2176)
1 parent 9a9188a commit 936e475

File tree

2 files changed

+100
-34
lines changed

2 files changed

+100
-34
lines changed

src/Utilities/functions.jl

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,67 @@
44
# Use of this source code is governed by an MIT-style license that can be found
55
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.
66

7+
# Functions convertible to a ScalarAffineFunction
8+
const ScalarAffineLike{T} =
9+
Union{T,MOI.VariableIndex,MOI.ScalarAffineFunction{T}}
10+
# Functions convertible to a ScalarQuadraticFunction
11+
const ScalarQuadraticLike{T} =
12+
Union{ScalarAffineLike{T},MOI.ScalarQuadraticFunction{T}}
13+
14+
# `ScalarLike` for which `T` is defined to avoid defining, e.g.,
15+
# `+(::VariableIndex, ::Any)` which should rather be
16+
# `+(::VariableIndex, ::Number)`.
17+
const TypedScalarLike{T} =
18+
Union{MOI.ScalarAffineFunction{T},MOI.ScalarQuadraticFunction{T}}
19+
# Used for overloading Base operator functions so `T` is not in the union to
20+
# avoid overloading e.g. `+(::Float64, ::Float64)`
21+
const ScalarLike{T} = Union{MOI.VariableIndex,TypedScalarLike{T}}
22+
23+
# Functions convertible to a VectorAffineFunction
24+
const VectorAffineLike{T} =
25+
Union{Vector{T},MOI.VectorOfVariables,MOI.VectorAffineFunction{T}}
26+
# Functions convertible to a VectorQuadraticFunction
27+
const VectorQuadraticLike{T} =
28+
Union{VectorAffineLike{T},MOI.VectorQuadraticFunction{T}}
29+
30+
# `VectorLike` for which `T` is defined to avoid defining, e.g.,
31+
# `+(::VectorOfVariables, ::Any)` which should rather be
32+
# `+(::VectorOfVariables, ::Number)`.
33+
const TypedVectorLike{T} =
34+
Union{MOI.VectorAffineFunction{T},MOI.VectorQuadraticFunction{T}}
35+
# Used for overloading Base operator functions so `T` is not in the union to
36+
# avoid overloading e.g. `+(::Float64, ::Float64)`
37+
const VectorLike{T} = Union{MOI.VectorOfVariables,TypedVectorLike{T}}
38+
39+
const TypedLike{T} = Union{TypedScalarLike{T},TypedVectorLike{T}}
40+
741
variable_function_type(::Type{<:MOI.AbstractScalarSet}) = MOI.VariableIndex
842
variable_function_type(::Type{<:MOI.AbstractVectorSet}) = MOI.VectorOfVariables
943

44+
"""
45+
value_type(::Type{T}, ::Type{F}) where {T,F<:AbstractFunction}
46+
47+
Returns the output type that results if a function of type `F` is evaluated
48+
using variables with numeric type `T`.
49+
50+
In other words, this is the return type for
51+
`MOI.Utilities.eval_variables(variable_values::Function, f::F)`
52+
for a function `variable_values(::MOI.VariableIndex)::T`.
53+
"""
54+
function value_type end
55+
56+
value_type(::Type{T}, ::Type{MOI.VariableIndex}) where {T} = T
57+
58+
value_type(::Type{T}, ::Type{MOI.VectorOfVariables}) where {T} = Vector{T}
59+
60+
function value_type(::Type{T}, ::Type{<:TypedScalarLike{C}}) where {C,T}
61+
return MA.promote_operation(*, C, T)
62+
end
63+
64+
function value_type(::Type{T}, ::Type{<:TypedVectorLike{C}}) where {C,T}
65+
return Vector{MA.promote_operation(*, C, T)}
66+
end
67+
1068
"""
1169
eval_variables(varval::Function, f::AbstractFunction)
1270
@@ -1494,40 +1552,6 @@ function map_terms!(
14941552
return map!(op, func.quadratic_terms, func.quadratic_terms)
14951553
end
14961554

1497-
# Functions convertible to a ScalarAffineFunction
1498-
const ScalarAffineLike{T} =
1499-
Union{T,MOI.VariableIndex,MOI.ScalarAffineFunction{T}}
1500-
# Functions convertible to a ScalarQuadraticFunction
1501-
const ScalarQuadraticLike{T} =
1502-
Union{ScalarAffineLike{T},MOI.ScalarQuadraticFunction{T}}
1503-
1504-
# `ScalarLike` for which `T` is defined to avoid defining, e.g.,
1505-
# `+(::VariableIndex, ::Any)` which should rather be
1506-
# `+(::VariableIndex, ::Number)`.
1507-
const TypedScalarLike{T} =
1508-
Union{MOI.ScalarAffineFunction{T},MOI.ScalarQuadraticFunction{T}}
1509-
# Used for overloading Base operator functions so `T` is not in the union to
1510-
# avoid overloading e.g. `+(::Float64, ::Float64)`
1511-
const ScalarLike{T} = Union{MOI.VariableIndex,TypedScalarLike{T}}
1512-
1513-
# Functions convertible to a VectorAffineFunction
1514-
const VectorAffineLike{T} =
1515-
Union{Vector{T},MOI.VectorOfVariables,MOI.VectorAffineFunction{T}}
1516-
# Functions convertible to a VectorQuadraticFunction
1517-
const VectorQuadraticLike{T} =
1518-
Union{VectorAffineLike{T},MOI.VectorQuadraticFunction{T}}
1519-
1520-
# `VectorLike` for which `T` is defined to avoid defining, e.g.,
1521-
# `+(::VectorOfVariables, ::Any)` which should rather be
1522-
# `+(::VectorOfVariables, ::Number)`.
1523-
const TypedVectorLike{T} =
1524-
Union{MOI.VectorAffineFunction{T},MOI.VectorQuadraticFunction{T}}
1525-
# Used for overloading Base operator functions so `T` is not in the union to
1526-
# avoid overloading e.g. `+(::Float64, ::Float64)`
1527-
const VectorLike{T} = Union{MOI.VectorOfVariables,TypedVectorLike{T}}
1528-
1529-
const TypedLike{T} = Union{TypedScalarLike{T},TypedVectorLike{T}}
1530-
15311555
###################################### +/- #####################################
15321556
## promote_operation
15331557

test/Utilities/functions.jl

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,6 +1792,48 @@ function test_SingleVariable_operators()
17921792
return
17931793
end
17941794

1795+
function test_value_type()
1796+
T = Float64
1797+
@test MOI.Utilities.value_type(T, MOI.VariableIndex) == T
1798+
@test MOI.Utilities.value_type(T, MOI.VectorOfVariables) == Vector{T}
1799+
@test MOI.Utilities.value_type(T, MOI.ScalarAffineFunction{Int}) == T
1800+
@test MOI.Utilities.value_type(T, MOI.ScalarAffineFunction{T}) == T
1801+
@test MOI.Utilities.value_type(T, MOI.ScalarAffineFunction{Complex{Int}}) ==
1802+
Complex{T}
1803+
@test MOI.Utilities.value_type(T, MOI.ScalarAffineFunction{Complex{T}}) ==
1804+
Complex{T}
1805+
@test MOI.Utilities.value_type(T, MOI.ScalarQuadraticFunction{Int}) == T
1806+
@test MOI.Utilities.value_type(T, MOI.ScalarQuadraticFunction{T}) == T
1807+
@test MOI.Utilities.value_type(
1808+
T,
1809+
MOI.ScalarQuadraticFunction{Complex{Int}},
1810+
) == Complex{T}
1811+
@test MOI.Utilities.value_type(
1812+
T,
1813+
MOI.ScalarQuadraticFunction{Complex{T}},
1814+
) == Complex{T}
1815+
@test MOI.Utilities.value_type(T, MOI.VectorAffineFunction{Int}) ==
1816+
Vector{T}
1817+
@test MOI.Utilities.value_type(T, MOI.VectorAffineFunction{T}) == Vector{T}
1818+
@test MOI.Utilities.value_type(T, MOI.VectorAffineFunction{Complex{Int}}) ==
1819+
Vector{Complex{T}}
1820+
@test MOI.Utilities.value_type(T, MOI.VectorAffineFunction{Complex{T}}) ==
1821+
Vector{Complex{T}}
1822+
@test MOI.Utilities.value_type(T, MOI.VectorQuadraticFunction{Int}) ==
1823+
Vector{T}
1824+
@test MOI.Utilities.value_type(T, MOI.VectorQuadraticFunction{T}) ==
1825+
Vector{T}
1826+
@test MOI.Utilities.value_type(
1827+
T,
1828+
MOI.VectorQuadraticFunction{Complex{Int}},
1829+
) == Vector{Complex{T}}
1830+
@test MOI.Utilities.value_type(
1831+
T,
1832+
MOI.VectorQuadraticFunction{Complex{T}},
1833+
) == Vector{Complex{T}}
1834+
return
1835+
end
1836+
17951837
end # module
17961838

17971839
TestFunctions.runtests()

0 commit comments

Comments
 (0)