Skip to content

Commit e2c9ff7

Browse files
committed
Add ExaModels wrapper
1 parent 3b3f82b commit e2c9ff7

File tree

6 files changed

+1160
-16
lines changed

6 files changed

+1160
-16
lines changed

examples/quad.jl

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
N = 3
2+
backend = nothing
3+
4+
n = 9
5+
p = 4
6+
d(i, j, N) =
7+
(j == 1 ? 1 * sin(2 * pi / N * i) : 0.0) +
8+
(j == 3 ? 2 * sin(4 * pi / N * i) : 0.0) +
9+
(j == 5 ? 2 * i / N : 0.0)
10+
dt = 1/N
11+
R = fill(1 / 10, 4)
12+
Q = [1, 0, 1, 0, 1, 0, 1, 1, 1]
13+
Qf = [1, 0, 1, 0, 1, 0, 1, 1, 1] / dt
14+
15+
x0 = zeros(n)
16+
17+
using JuMP
18+
model = Model()
19+
20+
@variable(model, x[1:(N+1), 1:n])
21+
@variable(model, u[1:N, 1:p])
22+
23+
using GenOpt
24+
container = ParametrizedArray
25+
26+
@constraint(
27+
model,
28+
[i in 1:n],
29+
x[1, i] == x0[i],
30+
container = container,
31+
)
32+
@constraint(
33+
model,
34+
[i in 1:N],
35+
x[i+1, 1] == x[i, 1] + (x[i, 2]) * dt,
36+
container = container,
37+
)
38+
@constraint(
39+
model,
40+
[i in 1:N],
41+
x[i+1, 2] ==
42+
x[i, 2] +
43+
(
44+
u[i, 1] * cos(x[i, 7]) * sin(x[i, 8]) * cos(x[i, 9]) +
45+
u[i, 1] * sin(x[i, 7]) * sin(x[i, 9])
46+
) * dt,
47+
container = container,
48+
)
49+
@constraint(
50+
model,
51+
[i in 1:N],
52+
x[i+1, 3] == x[i, 3] + (x[i, 4]) * dt,
53+
container = container,
54+
)
55+
@constraint(
56+
model,
57+
[i in 1:N],
58+
x[i+1, 4] ==
59+
x[i, 4] +
60+
(
61+
u[i, 1] * cos(x[i, 7]) * sin(x[i, 8]) * sin(x[i, 9]) -
62+
u[i, 1] * sin(x[i, 7]) * cos(x[i, 9])
63+
) * dt,
64+
container = container,
65+
)
66+
@constraint(
67+
model,
68+
[i in 1:N],
69+
x[i+1, 5] == x[i, 5] + (x[i, 6]) * dt,
70+
container = container,
71+
)
72+
@constraint(
73+
model,
74+
[i in 1:N],
75+
x[i+1, 6] == x[i, 6] + (u[i, 1] * cos(x[i, 7]) * cos(x[i, 8]) - 9.8) * dt,
76+
container = container,
77+
)
78+
@constraint(
79+
model,
80+
[i in 1:N],
81+
x[i+1, 7] ==
82+
x[i, 7] +
83+
(u[i, 2] * cos(x[i, 7]) / cos(x[i, 8]) + u[i, 3] * sin(x[i, 7]) / cos(x[i, 8])) * dt,
84+
container = container,
85+
)
86+
@constraint(
87+
model,
88+
[i in 1:N],
89+
x[i+1, 8] == x[i, 8] + (-u[i, 2] * sin(x[i, 7]) + u[i, 3] * cos(x[i, 7])) * dt,
90+
container = container,
91+
)
92+
@constraint(
93+
model,
94+
[i in 1:N],
95+
x[i+1, 9] ==
96+
x[i, 9] +
97+
(
98+
u[i, 2] * cos(x[i, 7]) * tan(x[i, 8]) +
99+
u[i, 3] * sin(x[i, 7]) * tan(x[i, 8]) +
100+
u[i, 4]
101+
) * dt,
102+
container = container,
103+
)
104+
105+
@objective(
106+
model,
107+
Min,
108+
sum(0.5 * R[j] * (u[i, j]^2) for i in 1:N, j in 1:p) +
109+
sum(0.5 * Q[j] * (x[i, j] - d(i, j, N))^2 for i in 1:N, j in 1:n) +
110+
sum(0.5 * Qf[j] * (x[N+1, j] - d(N + 1, j, N))^2 for j in 1:n),
111+
)
112+
113+
using NLPModelsIpopt
114+
set_optimizer(model, () -> GenOpt.ExaOptimizer(ipopt))
115+
optimize!(model)

src/GenOpt.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module GenOpt
77

88
include("MOI_wrapper.jl")
99
include("JuMP_wrapper.jl")
10+
include("examodels.jl")
1011

1112
# Copied from JuMP.jl:
1213
const _EXCLUDE_SYMBOLS = [Symbol(@__MODULE__), :eval, :include]

src/JuMP_wrapper.jl

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ include("operators.jl")
1515
end
1616
1717
Iterator `iterators[index.value]`.
18-
"""
18+
""" # TODO remove
1919
struct IteratorInExpr
2020
iterators::Iterators
2121
index::IteratorIndex
@@ -27,6 +27,38 @@ JuMP._is_real(::Union{IteratorInExpr,IteratorIndex}) = true
2727
JuMP.moi_function(i::Union{IteratorInExpr,IteratorIndex}) = i
2828
JuMP.jump_function(_, i::Union{IteratorInExpr,IteratorIndex}) = i
2929

30+
struct ArrayOfVariables{T,N} <: AbstractArray{JuMP.GenericVariableRef{T},N}
31+
model::JuMP.GenericModel{T}
32+
offset::Int64
33+
size::NTuple{N,Int64}
34+
end
35+
36+
Base.size(array::ArrayOfVariables) = array.size
37+
function Base.getindex(A::ArrayOfVariables{T}, I...) where {T}
38+
index = A.offset + Base._to_linear_index(Base.CartesianIndices(A.size), I...)
39+
return JuMP.GenericVariableRef{T}(A.model, MOI.VariableIndex(index))
40+
end
41+
42+
JuMP._is_real(::ArrayOfVariables) = true
43+
JuMP.moi_function(array::ArrayOfVariables) = ContiguousArrayOfVariables(array.offset, array.size)
44+
function JuMP.jump_function(model::JuMP.GenericModel{T}, array::ContiguousArrayOfVariables{N}) where {T,N}
45+
return ArrayOfVariables{T,N}(model, array.offset, array.size)
46+
end
47+
48+
function Base.convert(::Type{ArrayOfVariables{T,N}}, array::Array{JuMP.GenericVariableRef{T},N}) where {T,N}
49+
model = JuMP.owner_model(array[1])
50+
offset = JuMP.index(array[1]).value - 1
51+
for i in eachindex(array)
52+
@assert JuMP.owner_model(array[i]) === model
53+
@assert JuMP.index(array[i]).value == offset + i
54+
end
55+
return ArrayOfVariables{T,N}(model, offset, size(array))
56+
end
57+
58+
function to_generator(array::Array{JuMP.GenericVariableRef{T},N}) where {T,N}
59+
return convert(ArrayOfVariables{T,N}, array)
60+
end
61+
3062
struct ExprGenerator{E,V<:JuMP.AbstractVariableRef} <:
3163
AbstractVector{JuMP.GenericNonlinearExpr{V}}
3264
expr::ExprTemplate{E,V}

src/MOI_wrapper.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55

66
import MathOptInterface as MOI
77

8+
struct ContiguousArrayOfVariables{N} <: AbstractArray{MOI.VariableIndex,N}
9+
offset::Int64
10+
size::NTuple{N,Int64}
11+
end
12+
13+
Base.copy(array::ContiguousArrayOfVariables) = array
14+
Base.size(array::ContiguousArrayOfVariables) = array.size
15+
816
"""
917
struct Iterator{T}
1018
values::Vector{T}
@@ -14,6 +22,8 @@ struct Iterator{T}
1422
values::Vector{T}
1523
end
1624

25+
Iterator(values::AbstractArray) = Iterator(collect(values))
26+
1727
struct IteratorIndex
1828
value::Int
1929
end
@@ -31,3 +41,10 @@ end
3141
function MOI.Utilities.is_canonical(f::FunctionGenerator)
3242
return MOI.Utilities.is_canonical(f.func)
3343
end
44+
function MOI.Utilities.map_indices(::MOI.Utilities.IndexMap, func::FunctionGenerator)
45+
# TODO check it's identity
46+
return func
47+
end
48+
function MOI.Utilities.is_coefficient_type(::Type{FunctionGenerator{E}}, ::Type{T}) where {E,T}
49+
return MOI.Utilities.is_coefficient_type(E, T)
50+
end

0 commit comments

Comments
 (0)