|
1 | 1 | # Inspired by MathOptInterface/src/Nonlinear/parse_expression.jl |
2 | 2 |
|
| 3 | +const DEFAULT_MULTIVARIATE_OPERATORS = [ |
| 4 | + :+, |
| 5 | + :-, |
| 6 | + :*, |
| 7 | + :^, |
| 8 | + :/, |
| 9 | + :ifelse, |
| 10 | + :atan, |
| 11 | + :min, |
| 12 | + :max, |
| 13 | + :vect, |
| 14 | + :dot, |
| 15 | + :hcat, |
| 16 | + :vcat, |
| 17 | + :norm, |
| 18 | + :sum, |
| 19 | + :row, |
| 20 | +] |
| 21 | + |
| 22 | +struct OperatorRegistry |
| 23 | + # NODE_CALL_UNIVARIATE |
| 24 | + univariate_operators::Vector{Symbol} |
| 25 | + univariate_operator_to_id::Dict{Symbol,Int} |
| 26 | + univariate_user_operator_start::Int |
| 27 | + registered_univariate_operators::Vector{MOI.Nonlinear._UnivariateOperator} |
| 28 | + # NODE_CALL_MULTIVARIATE |
| 29 | + multivariate_operators::Vector{Symbol} |
| 30 | + multivariate_operator_to_id::Dict{Symbol,Int} |
| 31 | + multivariate_user_operator_start::Int |
| 32 | + registered_multivariate_operators::Vector{ |
| 33 | + MOI.Nonlinear._MultivariateOperator, |
| 34 | + } |
| 35 | + # NODE_LOGIC |
| 36 | + logic_operators::Vector{Symbol} |
| 37 | + logic_operator_to_id::Dict{Symbol,Int} |
| 38 | + # NODE_COMPARISON |
| 39 | + comparison_operators::Vector{Symbol} |
| 40 | + comparison_operator_to_id::Dict{Symbol,Int} |
| 41 | + function OperatorRegistry() |
| 42 | + univariate_operators = copy(DEFAULT_UNIVARIATE_OPERATORS) |
| 43 | + multivariate_operators = copy(DEFAULT_MULTIVARIATE_OPERATORS) |
| 44 | + logic_operators = [:&&, :||] |
| 45 | + comparison_operators = [:<=, :(==), :>=, :<, :>] |
| 46 | + return new( |
| 47 | + # NODE_CALL_UNIVARIATE |
| 48 | + univariate_operators, |
| 49 | + Dict{Symbol,Int}( |
| 50 | + op => i for (i, op) in enumerate(univariate_operators) |
| 51 | + ), |
| 52 | + length(univariate_operators), |
| 53 | + _UnivariateOperator[], |
| 54 | + # NODE_CALL |
| 55 | + multivariate_operators, |
| 56 | + Dict{Symbol,Int}( |
| 57 | + op => i for (i, op) in enumerate(multivariate_operators) |
| 58 | + ), |
| 59 | + length(multivariate_operators), |
| 60 | + _MultivariateOperator[], |
| 61 | + # NODE_LOGIC |
| 62 | + logic_operators, |
| 63 | + Dict{Symbol,Int}(op => i for (i, op) in enumerate(logic_operators)), |
| 64 | + # NODE_COMPARISON |
| 65 | + comparison_operators, |
| 66 | + Dict{Symbol,Int}( |
| 67 | + op => i for (i, op) in enumerate(comparison_operators) |
| 68 | + ), |
| 69 | + ) |
| 70 | + end |
| 71 | +end |
| 72 | + |
| 73 | +""" |
| 74 | + Model() |
| 75 | +
|
| 76 | +The core datastructure for representing a nonlinear optimization problem. |
| 77 | +
|
| 78 | +It has the following fields: |
| 79 | + * `objective::Union{Nothing,Expression}` : holds the nonlinear objective |
| 80 | + function, if one exists, otherwise `nothing`. |
| 81 | + * `expressions::Vector{Expression}` : a vector of expressions in the model. |
| 82 | + * `constraints::OrderedDict{ConstraintIndex,Constraint}` : a map from |
| 83 | + [`ConstraintIndex`](@ref) to the corresponding [`Constraint`](@ref). An |
| 84 | + `OrderedDict` is used instead of a `Vector` to support constraint deletion. |
| 85 | + * `parameters::Vector{Float64}` : holds the current values of the parameters. |
| 86 | + * `operators::OperatorRegistry` : stores the operators used in the model. |
| 87 | +""" |
| 88 | +mutable struct Model |
| 89 | + objective::Union{Nothing,MOI.Nonlinear.Expression} |
| 90 | + expressions::Vector{MOI.Nonlinear.Expression} |
| 91 | + constraints::OrderedDict{ |
| 92 | + MOI.Nonlinear.ConstraintIndex, |
| 93 | + MOI.Nonlinear.Constraint, |
| 94 | + } |
| 95 | + parameters::Vector{Float64} |
| 96 | + operators::OperatorRegistry |
| 97 | + # This is a private field, used only to increment the ConstraintIndex. |
| 98 | + last_constraint_index::Int64 |
| 99 | + function Model() |
| 100 | + model = MOI.Nonlinear.Model() |
| 101 | + ops = [:vect, :dot, :hcat, :vcat, :norm, :sum, :row] |
| 102 | + start = length(model.operators.multivariate_operators) |
| 103 | + append!(model.operators.multivariate_operators, ops) |
| 104 | + for (i, op) in enumerate(ops) |
| 105 | + model.operators.multivariate_operator_to_id[op] = start + i |
| 106 | + end |
| 107 | + return model |
| 108 | + end |
| 109 | +end |
| 110 | + |
3 | 111 | function set_objective(model::MOI.Nonlinear.Model, obj) |
4 | 112 | model.objective = parse_expression(model, obj) |
5 | 113 | return |
6 | 114 | end |
7 | 115 |
|
8 | | -function Model() |
9 | | - model = MOI.Nonlinear.Model() |
10 | | - append!( |
11 | | - model.operators.multivariate_operators, |
12 | | - [:vect, :dot, :hcat, :vcat, :norm, :sum, :row], |
13 | | - ) |
14 | | - return model |
15 | | -end |
16 | | - |
17 | 116 | function parse_expression(data::MOI.Nonlinear.Model, input) |
18 | 117 | expr = MOI.Nonlinear.Expression() |
19 | 118 | parse_expression(data, expr, input, -1) |
|
0 commit comments