Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
2 changes: 1 addition & 1 deletion docs/src/guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ The following functions should be defined:
- `cons_nln!(nlp, x, c)`
- `jac_lin_structure!(nlp, jrows, jcols)`
- `jac_nln_structure!(nlp, jrows, jcols)`
- `jac_lin_coord!(nlp, x, jvals)`
- `jac_lin_coord!(nlp, jvals)`
- `jac_nln_coord!(nlp, x, jvals)`
- `jprod_lin!(nlp, x, v, Jv)`
- `jprod_nln!(nlp, x, v, Jv)`
Expand Down
63 changes: 40 additions & 23 deletions src/nlp/api.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Base: @deprecate

export obj, grad, grad!, objgrad, objgrad!, objcons, objcons!
export cons, cons!, cons_lin, cons_lin!, cons_nln, cons_nln!
export jth_con, jth_congrad, jth_congrad!, jth_sparse_congrad
Expand Down Expand Up @@ -307,36 +309,43 @@ function jac(nlp::AbstractNLPModel, x::AbstractVector)
end

"""
vals = jac_lin_coord!(nlp, x, vals)
vals = jac_lin_coord!(nlp, vals)

Evaluate ``J(x)``, the linear constraints Jacobian at `x` in sparse coordinate format,
Evaluate the linear constraints Jacobian in sparse coordinate format,
overwriting `vals`.
"""
function jac_lin_coord! end

# Deprecated version with x parameter
@deprecate jac_lin_coord!(nlp::AbstractNLPModel, x::AbstractVector, vals::AbstractVector) jac_lin_coord!(nlp, vals)

"""
vals = jac_lin_coord(nlp, x)
vals = jac_lin_coord(nlp)

Evaluate ``J(x)``, the linear constraints Jacobian at `x` in sparse coordinate format.
Evaluate the linear constraints Jacobian in sparse coordinate format.
"""
function jac_lin_coord(nlp::AbstractNLPModel{T, S}, x::AbstractVector) where {T, S}
@lencheck nlp.meta.nvar x
function jac_lin_coord(nlp::AbstractNLPModel{T, S}) where {T, S}
vals = S(undef, nlp.meta.lin_nnzj)
return jac_lin_coord!(nlp, x, vals)
return jac_lin_coord!(nlp, vals)
end

# Deprecated version with x parameter
@deprecate jac_lin_coord(nlp::AbstractNLPModel, x::AbstractVector) jac_lin_coord(nlp)

"""
Jx = jac_lin(nlp, x)
Jx = jac_lin(nlp)

Evaluate ``J(x)``, the linear constraints Jacobian at `x` as a sparse matrix.
Evaluate the linear constraints Jacobian as a sparse matrix.
"""
function jac_lin(nlp::AbstractNLPModel, x::AbstractVector)
@lencheck nlp.meta.nvar x
function jac_lin(nlp::AbstractNLPModel)
rows, cols = jac_lin_structure(nlp)
vals = jac_lin_coord(nlp, x)
vals = jac_lin_coord(nlp)
sparse(rows, cols, vals, nlp.meta.nlin, nlp.meta.nvar)
end

# Deprecated version with x parameter
@deprecate jac_lin(nlp::AbstractNLPModel, x::AbstractVector) jac_lin(nlp)

"""
vals = jac_nln_coord!(nlp, x, vals)

Expand Down Expand Up @@ -736,37 +745,40 @@ function jac_op!(
end

"""
J = jac_lin_op(nlp, x)
J = jac_lin_op(nlp)

Return the linear Jacobian at `x` as a linear operator.
Return the linear Jacobian as a linear operator.
The resulting object may be used as if it were a matrix, e.g., `J * v` or
`J' * v`.
"""
function jac_lin_op(nlp::AbstractNLPModel{T, S}, x::AbstractVector) where {T, S}
@lencheck nlp.meta.nvar x
function jac_lin_op(nlp::AbstractNLPModel{T, S}) where {T, S}
Jv = S(undef, nlp.meta.nlin)
Jtv = S(undef, nlp.meta.nvar)
return jac_lin_op!(nlp, x, Jv, Jtv)
return jac_lin_op!(nlp, Jv, Jtv)
end

# Deprecated version with x parameter
@deprecate jac_lin_op(nlp::AbstractNLPModel, x::AbstractVector) jac_lin_op(nlp)

"""
J = jac_lin_op!(nlp, x, Jv, Jtv)
J = jac_lin_op!(nlp, Jv, Jtv)

Return the linear Jacobian at `x` as a linear operator.
Return the linear Jacobian as a linear operator.
The resulting object may be used as if it were a matrix, e.g., `J * v` or
`J' * v`. The values `Jv` and `Jtv` are used as preallocated storage for the
operations.
"""
function jac_lin_op!(
nlp::AbstractNLPModel{T, S},
x::AbstractVector{T},
Jv::AbstractVector,
Jtv::AbstractVector,
) where {T, S}
@lencheck nlp.meta.nvar x Jtv
@lencheck nlp.meta.nlin Jv
@lencheck nlp.meta.nvar Jtv
prod! = @closure (res, v, α, β) -> begin # res = α * J * v + β * res
jprod_lin!(nlp, x, v, Jv)
rows, cols = jac_lin_structure(nlp)
vals = jac_lin_coord(nlp)
jprod_lin!(nlp, rows, cols, vals, v, Jv)
if β == 0
res .= α .* Jv
else
Expand All @@ -775,7 +787,9 @@ function jac_lin_op!(
return res
end
ctprod! = @closure (res, v, α, β) -> begin
jtprod_lin!(nlp, x, v, Jtv)
rows, cols = jac_lin_structure(nlp)
vals = jac_lin_coord(nlp)
jtprod_lin!(nlp, rows, cols, vals, v, Jtv)
if β == 0
res .= α .* Jtv
else
Expand All @@ -786,6 +800,9 @@ function jac_lin_op!(
return LinearOperator{T}(nlp.meta.nlin, nlp.meta.nvar, false, false, prod!, ctprod!, ctprod!)
end

# Deprecated version with x parameter
@deprecate jac_lin_op!(nlp::AbstractNLPModel, x::AbstractVector, Jv::AbstractVector, Jtv::AbstractVector) jac_lin_op!(nlp, Jv, Jtv)

"""
J = jac_lin_op!(nlp, rows, cols, vals, Jv, Jtv)

Expand Down
10 changes: 5 additions & 5 deletions test/nlp/api.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
@test cons_lin(nlp, x) == c(x)[1:1]
@test jac(nlp, x) ≈ J(x)
@test jac_nln(nlp, x) ≈ J(x)[2:2, :]
@test jac_lin(nlp, x) ≈ J(x)[1:1, :]
@test jac_lin(nlp) ≈ J(x)[1:1, :]
@test jprod(nlp, x, v) ≈ J(x) * v
@test jprod_nln(nlp, x, v) ≈ J(x)[2:2, :] * v
@test jprod_lin(nlp, x, v) ≈ J(x)[1:1, :] * v
Expand All @@ -56,12 +56,12 @@
@test jprod!(nlp, jac_structure(nlp)..., jac_coord(nlp, x), v, Jv) ≈ J(x) * v
@test jprod_nln!(nlp, jac_nln_structure(nlp)..., jac_nln_coord(nlp, x), v, Jv[2:2]) ≈
J(x)[2:2, :] * v
@test jprod_lin!(nlp, jac_lin_structure(nlp)..., jac_lin_coord(nlp, x), v, Jv[1:1]) ≈
@test jprod_lin!(nlp, jac_lin_structure(nlp)..., jac_lin_coord(nlp), v, Jv[1:1]) ≈
J(x)[1:1, :] * v
@test jtprod!(nlp, jac_structure(nlp)..., jac_coord(nlp, x), w, Jtw) ≈ J(x)' * w
@test jtprod_nln!(nlp, jac_nln_structure(nlp)..., jac_nln_coord(nlp, x), w[2:2], Jtw) ≈
J(x)[2:2, :]' * w[2:2]
@test jtprod_lin!(nlp, jac_lin_structure(nlp)..., jac_lin_coord(nlp, x), w[1:1], Jtw) ≈
@test jtprod_lin!(nlp, jac_lin_structure(nlp)..., jac_lin_coord(nlp), w[1:1], Jtw) ≈
J(x)[1:1, :]' * w[1:1]
Jop = jac_op!(nlp, x, Jv, Jtw)
@test Jop * v ≈ J(x) * v
Expand Down Expand Up @@ -91,14 +91,14 @@
@test mul!(w[2:2], Jop, v, 1.0, -1.0) ≈ res
res = J(x)[2:2, :]' * w[2:2] - v
@test mul!(v, Jop', w[2:2], 1.0, -1.0) ≈ res
Jop = jac_lin_op!(nlp, x, Jv[1:1], Jtw)
Jop = jac_lin_op!(nlp, Jv[1:1], Jtw)
@test Jop * v ≈ J(x)[1:1, :] * v
@test Jop' * w[1:1] ≈ Jtw
res = J(x)[1:1, :] * v - w[1:1]
@test mul!(w[1:1], Jop, v, 1.0, -1.0) ≈ res
res = J(x)[1:1, :]' * w[1:1] - v
@test mul!(v, Jop', w[1:1], 1.0, -1.0) ≈ res
Jop = jac_lin_op!(nlp, jac_lin_structure(nlp)..., jac_lin_coord(nlp, x), Jv[1:1], Jtw)
Jop = jac_lin_op!(nlp, jac_lin_structure(nlp)..., jac_lin_coord(nlp), Jv[1:1], Jtw)
@test Jop * v ≈ J(x)[1:1, :] * v
@test Jop' * w[1:1] ≈ Jtw
res = J(x)[1:1, :] * v - w[1:1]
Expand Down
2 changes: 1 addition & 1 deletion test/nlp/dummy-model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ end
@test_throws(MethodError, ghjvprod!(model, [0.0], [1.0], [2.0], [3.0]))
@assert isa(hess_op(model, [0.0]), LinearOperator)
@assert isa(jac_op(model, [0.0]), LinearOperator)
@assert isa(jac_lin_op(model, [0.0]), LinearOperator)
@assert isa(jac_lin_op(model), LinearOperator)
@assert isa(jac_nln_op(model, [0.0]), LinearOperator)
end
4 changes: 2 additions & 2 deletions test/nlp/simple-model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ function NLPModels.jac_nln_coord!(nlp::SimpleNLPModel, x::AbstractVector, vals::
return vals
end

function NLPModels.jac_lin_coord!(nlp::SimpleNLPModel, x::AbstractVector, vals::AbstractVector)
@lencheck 2 x vals
function NLPModels.jac_lin_coord!(nlp::SimpleNLPModel, vals::AbstractVector)
@lencheck 2 vals
increment!(nlp, :neval_jac_lin)
vals .= [1, -2]
return vals
Expand Down
Loading