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

[docs] add section on function tracing #3570

Merged
merged 3 commits into from
Nov 12, 2023
Merged
Changes from 2 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
59 changes: 59 additions & 0 deletions docs/src/manual/nonlinear.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,65 @@
x
```

## Function tracing

Nonlinear expressions can be constructed using _function tracing_. Function
tracing is when you call a regular Julia function with JuMP variables as
arguments and the function builds a nonlinear expression via operator
overloading. For example:

```@repl
using JuMP
model = Model();
@variable(model, x[1:2]);
f(x::Vector{VariableRef}) = 2 * sin(x[1]^2) + sqrt(x[2])
y = f(x)
typeof(y)
@objective(model, Max, f(x))
```

Function tracing supports functions which return vectors or arrays of
[`NonlinearExpr`](@ref):

```@repl
using JuMP
model = Model();
@variable(model, x[1:2]);
f(x::Vector{VariableRef}) = sqrt.(x)
y = f(x)
typeof(y)
@constraint(model, f(x) .<= 2)
@objective(model, Max, sum(f(x)))
```

Because function tracing uses operator overloading, there are many functions for
which it will not work. For example:

```jldoctest
julia> using JuMP

julia> model = Model();

julia> @variable(model, x[1:2]);

julia> f(x::Vector{VariableRef}) = x[1] > 1 ? 0 : x[2]
odow marked this conversation as resolved.
Show resolved Hide resolved
f (generic function with 1 method)

julia> f(x)
ERROR: Cannot evaluate `>` between a variable and a number.
[...]
```

In these cases, you should define a [User-defined operator](@ref jump_user_defined_operators)
using the [`@operator`](@ref) macro.

!!! tip
If it works, in most cases, you should prefer to use function tracing
instead of defining a user-defined operator. One exception is when the
function returns a very large expression (for example, it includes a
summation over a million elements). In that case, the user-defined operator
can be more effiicent.

Check failure on line 365 in docs/src/manual/nonlinear.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/src/manual/nonlinear.md#L365

[Vale.Spelling] Did you really mean 'effiicent'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'effiicent'?", "location": {"path": "docs/src/manual/nonlinear.md", "range": {"start": {"line": 365, "column": 17}}}, "severity": "ERROR"}
blegat marked this conversation as resolved.
Show resolved Hide resolved

## [User-defined operators](@id jump_user_defined_operators)

In addition to a standard list of univariate and multivariate operators
Expand Down
Loading