Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Pluralization of @NLparameters (#2593) #2619

Merged
merged 3 commits into from
Jun 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/reference/nlp.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ set_NL_objective

```@docs
@NLparameter
@NLparameters
NonlinearParameter
value(::JuMP.NonlinearParameter)
set_value(::JuMP.NonlinearParameter, ::Number)
Expand Down
65 changes: 45 additions & 20 deletions src/macros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ end
"""
_add_positional_args(call, args)::Nothing

Add the positional arguments `args` to the function call expression `call`,
escaping each argument expression. The elements of `args` should be ones that
were extracted via [`Containers._extract_kw_args`](@ref) and had appropriate
arguments filtered out (e.g., the model argument). This is able to incorporate
Add the positional arguments `args` to the function call expression `call`,
escaping each argument expression. The elements of `args` should be ones that
were extracted via [`Containers._extract_kw_args`](@ref) and had appropriate
arguments filtered out (e.g., the model argument). This is able to incorporate
additional positional arguments to `call`s that already have keyword arguments.

## Examples
## Examples

```jldoctest; setup = :(using JuMP)
julia> call = :(f(1, a=2))
Expand Down Expand Up @@ -569,10 +569,10 @@ where `@constraint_like` is either `@constraint` or `@SDconstraint`.
The expression `con` is parsed by `parsefun` which returns a `build_constraint`
call code that, when executed, returns an `AbstractConstraint`. The macro
keyword arguments (except the `container` keyword argument which is used to
determine the container type) are added to the `build_constraint` call. The
`extra_arg` is added as terminal positional argument to the `build_constraint`
call along with any keyword arguments (apart from `container` and `base_name`).
The returned value of this call is passed to `add_constraint` which returns a
determine the container type) are added to the `build_constraint` call. The
`extra_arg` is added as terminal positional argument to the `build_constraint`
call along with any keyword arguments (apart from `container` and `base_name`).
The returned value of this call is passed to `add_constraint` which returns a
constraint reference.

`source` is a `LineNumberNode` that should refer to the line that the macro was
Expand Down Expand Up @@ -611,7 +611,7 @@ function _constraint_macro(
# name[i = 1:2, j = 1:2; i + j >= 3] | Expr | :typed_vcat
# [1:2] | Expr | :vect
# [i = 1:2, j = 1:2; i + j >= 3] | Expr | :vcat
# a constraint expression | Expr | :call or :comparison
# a constraint expression | Expr | :call or :comparison
if isa(y, Symbol) || isexpr(y, (:vect, :vcat, :ref, :typed_vcat))
length(extra) >= 1 || _error("No constraint expression was given.")
c = y
Expand All @@ -623,16 +623,16 @@ function _constraint_macro(
anonvar = true
end

# Enforce that only one extra positional argument can be given
# Enforce that only one extra positional argument can be given
if length(extra) > 1
_error("Cannot specify more than 1 additional positional argument.")
end

# Prepare the keyword arguments
# Prepare the keyword arguments
extra_kw_args = filter(kw -> kw.args[1] != :base_name, kw_args)
base_name_kw_args = filter(kw -> kw.args[1] == :base_name, kw_args)

# Set the base name
# Set the base name
name = Containers._get_name(c)
if isempty(base_name_kw_args)
base_name = anonvar ? "" : string(name)
Expand Down Expand Up @@ -766,12 +766,12 @@ that either `func` or `set` will be some custom type, rather than e.g. a
`Symbol`, since we will likely want to dispatch on the type of the function or
set appearing in the constraint.

For extensions that need to create constraints with more information than just
`func` and `set`, an additional positional argument can be specified to
`@constraint` that will then be passed on `build_constraint`. Hence, we can
enable this syntax by defining extensions of
`build_constraint(_error, func, set, my_arg; kw_args...)`. This produces the
user syntax: `@constraint(model, ref[...], expr, my_arg, kw_args...)`.
For extensions that need to create constraints with more information than just
`func` and `set`, an additional positional argument can be specified to
`@constraint` that will then be passed on `build_constraint`. Hence, we can
enable this syntax by defining extensions of
`build_constraint(_error, func, set, my_arg; kw_args...)`. This produces the
user syntax: `@constraint(model, ref[...], expr, my_arg, kw_args...)`.
"""
macro constraint(args...)
return _constraint_macro(
Expand Down Expand Up @@ -946,6 +946,7 @@ end
_add_JuMP_prefix(s::Symbol) = Expr(:., JuMP, :($(QuoteNode(s))))

for (mac, sym) in [
(:NLparameters, Symbol("@NLparameter")),
(:constraints, Symbol("@constraint")),
(:NLconstraints, Symbol("@NLconstraint")),
(:SDconstraints, Symbol("@SDconstraint")),
Expand Down Expand Up @@ -1092,6 +1093,30 @@ end)
```
""" :(@SDconstraints)

@doc """
@NLparameters(model, args...)

Create and return multiple nonlinear parameters attached to model `model`, in the same fashion as
[`@NLparameter`](@ref) macro.

The model must be the first argument, and multiple parameters can be added on
multiple lines wrapped in a `begin ... end` block. Distinct parameters need to be placed
on separate lines as in the following example.

# Example
```jldoctest; setup=:(using JuMP)
model = Model()
@NLparameters(model, begin
x == 10
b == 156
end)
value(x)

# output
10.0
```
""" :(@NLparameters)

@doc """
@NLconstraints(model, args...)

Expand Down Expand Up @@ -1576,7 +1601,7 @@ arguments `kw_args` and returns the variable.
Add a variable to the model `model` described by the expression `expr`, the
positional arguments `args` and the keyword arguments `kw_args`. The expression
`expr` can either be (note that in the following the symbol `<=` can be used
instead of `≤`, the symbol `>=`can be used instead of `≥`, the symbol `in` can be
instead of `≤`, the symbol `>=`can be used instead of `≥`, the symbol `in` can be
used instead of `∈`)

* of the form `varexpr` creating variables described by `varexpr`;
Expand Down
10 changes: 10 additions & 0 deletions test/macros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,16 @@ end
"""
end

@testset "NLparameters" begin
model = Model()
@NLparameters(model, begin
a == 1
b[i = 1:2] == i
end)
@test value(a) == 1
@test value.(b) == [1, 2]
end

@testset "Index variables don't leak out of macros" begin
model = Model()
i = 10
Expand Down