Skip to content

Commit dc47126

Browse files
authored
Merge pull request #392 from JuliaOpt/bl/output_dimension
Define output_dimension
2 parents 87f6e6e + fc118c4 commit dc47126

File tree

6 files changed

+35
-9
lines changed

6 files changed

+35
-9
lines changed

docs/src/apireference.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,12 @@ VectorQuadraticTerm
201201
VectorQuadraticFunction
202202
```
203203

204+
Functions for getting and setting properties of sets.
205+
206+
```@docs
207+
output_dimension
208+
```
209+
204210
List of function modifications.
205211
```@docs
206212
ScalarConstantChange

src/Bridges/soctopsdbridge.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Builds a VectorAffineFunction representing the upper (or lower) triangular part
66
[ f[2:end] g * I ]
77
"""
88
function _SOCtoPSDCaff(f::MOI.VectorAffineFunction{T}, g::MOI.ScalarAffineFunction{T}) where T
9-
dim = MOIU.moilength(f)
9+
dim = MOI.output_dimension(f)
1010
n = div(dim * (dim+1), 2)
1111
# Needs to add t*I
1212
N0 = length(f.terms)
@@ -125,7 +125,7 @@ end
125125

126126
_RSOCtoPSDCaff(f::MOI.VectorOfVariables, ::Type{T}) where T = _RSOCtoPSDCaff(MOI.VectorAffineFunction{T}(f), T)
127127
function _RSOCtoPSDCaff(f::MOI.VectorAffineFunction, ::Type)
128-
n = MOIU.moilength(f)
128+
n = MOI.output_dimension(f)
129129
g = mapcoefficient(c -> 2c, MOIU.eachscalar(f)[2])
130130
_SOCtoPSDCaff(MOIU.eachscalar(f)[[1; 3:n]], g)
131131
end

src/Utilities/functions.jl

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@ mapvariables(varmap::Function, change::MOI.MultirowChange) = MOI.MultirowChange(
5555
mapvariables(varmap, f::MOI.AbstractFunctionModification) = mapvariables(vi -> varmap[vi], f)
5656

5757
# Cat for MOI sets
58-
moilength(f::Union{MOI.ScalarAffineFunction, MOI.ScalarQuadraticFunction}) = 1
59-
moilength(f::Union{MOI.VectorAffineFunction, MOI.VectorQuadraticFunction}) = length(f.constants)
6058
_constant(f::Union{MOI.ScalarAffineFunction, MOI.ScalarQuadraticFunction}) = f.constant
6159
_constant(f::Union{MOI.VectorAffineFunction, MOI.VectorQuadraticFunction}) = f.constants
6260
constant(f::Union{MOI.ScalarAffineFunction, MOI.ScalarQuadraticFunction}) = [f.constant]
@@ -66,7 +64,7 @@ offsetterm(t::MOI.VectorAffineTerm, offset::Int) = MOI.VectorAffineTerm(offset+t
6664
offsetterms(f::Union{MOI.ScalarAffineFunction, MOI.VectorAffineFunction}, offset::Int) = offsetterm.(f.terms, offset)
6765
function moivcat(f::Union{MOI.ScalarAffineFunction, MOI.VectorAffineFunction}...)
6866
n = length(f)
69-
offsets = cumsum(collect(moilength.(f)))
67+
offsets = cumsum(collect(MOI.output_dimension.(f)))
7068
offsets = [0; offsets[1:(n-1)]]
7169
terms = vcat((offsetterms.(f, offsets))...)
7270
cst = vcat(constant.(f)...)
@@ -91,7 +89,7 @@ Base.start(it::ScalarFunctionIterator) = 1
9189
Base.done(it::ScalarFunctionIterator, state) = state > length(it)
9290
Base.next(it::ScalarFunctionIterator, state) = (it[state], state+1)
9391
Base.length(it::ScalarFunctionIterator{MOI.VectorOfVariables}) = length(it.f.variables)
94-
Base.length(it::ScalarFunctionIterator{<:Union{MOI.VectorAffineFunction, MOI.VectorQuadraticFunction}}) = moilength(it.f)
92+
Base.length(it::ScalarFunctionIterator{<:Union{MOI.VectorAffineFunction, MOI.VectorQuadraticFunction}}) = MOI.output_dimension(it.f)
9593
Base.eltype(it::ScalarFunctionIterator{MOI.VectorOfVariables}) = MOI.SingleVariable
9694
Base.eltype(it::ScalarFunctionIterator{MOI.VectorAffineFunction{T}}) where T = MOI.ScalarAffineFunction{T}
9795
Base.eltype(it::ScalarFunctionIterator{MOI.VectorQuadraticFunction{T}}) where T = MOI.ScalarQuadraticFunction{T}
@@ -362,9 +360,9 @@ function _modifycoefficients(n, terms::Vector{<:MOI.VectorAffineTerm}, variable:
362360
terms
363361
end
364362
function modifyfunction(f::MOI.VectorAffineFunction, change::MOI.MultirowChange)
365-
MOI.VectorAffineFunction(_modifycoefficients(moilength(f), f.terms, change.variable, change.new_coefficients), f.constants)
363+
MOI.VectorAffineFunction(_modifycoefficients(MOI.output_dimension(f), f.terms, change.variable, change.new_coefficients), f.constants)
366364
end
367365
function modifyfunction(f::MOI.VectorQuadraticFunction, change::MOI.MultirowChange)
368-
MOI.VectorQuadraticFunction(_modifycoefficients(moilength(f), f.affine_terms, change.variable, change.new_coefficients),
366+
MOI.VectorQuadraticFunction(_modifycoefficients(MOI.output_dimension(f), f.affine_terms, change.variable, change.new_coefficients),
369367
f.quadratic_terms, f.constants)
370368
end

src/functions.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,21 @@ Abstract supertype for function objects.
77
"""
88
abstract type AbstractFunction end
99

10+
"""
11+
output_dimension(f::AbstractFunction)
12+
13+
Return 1 if `f` has a scalar output and the number of output components if `f`
14+
has a vector output.
15+
"""
16+
function output_dimension end
17+
1018
"""
1119
AbstractScalarFunction
1220
1321
Abstract supertype for scalar-valued function objects.
1422
"""
1523
abstract type AbstractScalarFunction <: AbstractFunction end
24+
output_dimension(::AbstractScalarFunction) = 1
1625

1726
"""
1827
AbstractVectorFunction
@@ -41,6 +50,7 @@ This function is naturally be used for constraints that apply to groups of varia
4150
struct VectorOfVariables <: AbstractVectorFunction
4251
variables::Vector{VariableIndex}
4352
end
53+
output_dimension(f::VectorOfVariables) = length(f.variables)
4454

4555
"""
4656
struct ScalarAffineTerm{T}
@@ -110,6 +120,7 @@ struct VectorAffineFunction{T} <: AbstractVectorFunction
110120
terms::Vector{VectorAffineTerm{T}}
111121
constants::Vector{T}
112122
end
123+
output_dimension(f::VectorAffineFunction) = length(f.constants)
113124

114125
"""
115126
struct ScalarQuadraticTerm{T}
@@ -193,6 +204,7 @@ struct VectorQuadraticFunction{T} <: AbstractVectorFunction
193204
quadratic_terms::Vector{VectorQuadraticTerm{T}}
194205
constants::Vector{T}
195206
end
207+
output_dimension(f::VectorQuadraticFunction) = length(f.constants)
196208

197209
# Function modifications
198210

src/sets.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ abstract type AbstractSet end
1010
"""
1111
dimension(s::AbstractSet)
1212
13-
Return the output dimension that an [`AbstractFunction`](@ref) should have to be used with the set `s`.
13+
Return the [`output_dimension`](@ref) that an [`AbstractFunction`](@ref) should have to be used with the set `s`.
1414
1515
### Examples
1616

test/functions.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,29 @@
1515
# We do tests twice to make sure the function is not modified
1616
vals = Dict(w=>0, x=>3, y=>1, z=>5)
1717
fsv = MOI.SingleVariable(z)
18+
@test MOI.output_dimension(fsv) == 1
1819
@test MOIU.evalvariables(vi -> vals[vi], fsv) 5
1920
@test MOIU.evalvariables(vi -> vals[vi], fsv) 5
2021
fvv = MOI.VectorOfVariables([x, z, y])
22+
@test MOI.output_dimension(fvv) == 3
2123
@test MOIU.evalvariables(vi -> vals[vi], fvv) [3, 5, 1]
2224
@test MOIU.evalvariables(vi -> vals[vi], fvv) [3, 5, 1]
2325
fsa = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x), MOI.ScalarAffineTerm(3.0, z), MOI.ScalarAffineTerm(2.0, y)], 2.0)
26+
@test MOI.output_dimension(fsa) == 1
2427
@test MOIU.evalvariables(vi -> vals[vi], fsa) 22
2528
@test MOIU.evalvariables(vi -> vals[vi], fsa) 22
2629
fva = MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2, 1, 2], MOI.ScalarAffineTerm.([1.0, 3.0, 2.0], [x, z, y])), [-3.0, 2.0])
30+
@test MOI.output_dimension(fva) == 2
2731
@test MOIU.evalvariables(vi -> vals[vi], fva) [12, 7]
2832
@test MOIU.evalvariables(vi -> vals[vi], fva) [12, 7]
2933
fsq = MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm.(1.0, [x, y]),
3034
MOI.ScalarQuadraticTerm.(1.0, [x, w, w], [z, z, y]), -3.0)
35+
@test MOI.output_dimension(fsq) == 1
3136
@test MOIU.evalvariables(vi -> vals[vi], fsq) 16
3237
@test MOIU.evalvariables(vi -> vals[vi], fsq) 16
3338
fvq = MOI.VectorQuadraticFunction(MOI.VectorAffineTerm.([2, 1], MOI.ScalarAffineTerm.(1.0, [x, y])),
3439
MOI.VectorQuadraticTerm.([1, 2, 2], MOI.ScalarQuadraticTerm.(1.0, [x, w, w], [z, z, y])), [-3.0, -2.0])
40+
@test MOI.output_dimension(fvq) == 2
3541
@test MOIU.evalvariables(vi -> vals[vi], fvq) [13, 1]
3642
@test MOIU.evalvariables(vi -> vals[vi], fvq) [13, 1]
3743
end
@@ -127,6 +133,7 @@
127133
@test MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1, 1], [x, z]), 1) MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1, 1e-7, 1], [x, y, z]), 1.0) atol=1e-6
128134
@test MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x), MOI.ScalarAffineTerm(1e-7, y)], 1.0) MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1, x)], 1) atol=1e-6
129135
f = MOIU.canonical(MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2, 1, 3, -2, -3], [y, x, z, x, z]), 5))
136+
@test MOI.output_dimension(f) == 1
130137
@test f.terms == MOI.ScalarAffineTerm.([-1, 2], [x, y])
131138
@test f.constant == 5
132139
f = MOIU.canonical(MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1, 3, 1, 2, -3, 2, -1, -2, -2, 3, 2],
@@ -146,6 +153,7 @@
146153
end
147154
@testset "Quadratic" begin
148155
f = MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm.([3], [x]), MOI.ScalarQuadraticTerm.([1, 2, 3], [x, y, x], [x, y, y]), 7)
156+
@test MOI.output_dimension(f) == 1
149157
f = MOIU.modifyfunction(f, MOI.ScalarConstantChange(9))
150158
@test f.constant == 9
151159
f = MOIU.modifyfunction(f, MOI.ScalarCoefficientChange(y, 0))
@@ -163,6 +171,7 @@
163171
f = MOIU.canonical(MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2, 1, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 1, 2],
164172
MOI.ScalarAffineTerm.([3, 2, 3, -3, -1, -2, 3, -2, 1, 3, 5, -2, 0, -1],
165173
[x, x, z, y, y, x, y, z, x, y, y, x, x, z])), [5, 7]))
174+
@test MOI.output_dimension(f) == 2
166175
@test f.terms == MOI.VectorAffineTerm.([1, 1, 2], MOI.ScalarAffineTerm.([2, 4, 3], [x, y, y]))
167176
@test MOIU.constant(f) == [5, 7]
168177
f = MOIU.modifyfunction(f, MOI.VectorConstantChange([6, 8]))
@@ -178,6 +187,7 @@
178187
end
179188
@testset "Quadratic" begin
180189
f = MOI.VectorQuadraticFunction(MOI.VectorAffineTerm.([1, 2, 2], MOI.ScalarAffineTerm.([3, 1, 2], [x, x, y])), MOI.VectorQuadraticTerm.([1, 1, 2], MOI.ScalarQuadraticTerm.([1, 2, 3], [x, y, x], [x, y, y])), [7, 3, 4])
190+
@test MOI.output_dimension(f) == 3
181191
f = MOIU.modifyfunction(f, MOI.VectorConstantChange([10, 11, 12]))
182192
@test MOIU.constant(f) == [10, 11, 12]
183193
f = MOIU.modifyfunction(f, MOI.MultirowChange(y, [(2, 0), (1, 1)]))

0 commit comments

Comments
 (0)