Skip to content
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
26 changes: 10 additions & 16 deletions src/symbolic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,47 +20,41 @@ function SymbolicFunction(f, _x::AbstractVector; hessian = false, sparse = false
if val isa Real
if sparse
sgrad = Symbolics.sparsejacobian([f(x)], x; simplify)
f_expr = Symbolics.build_function(sgrad, x)[1]
_g = eval(f_expr)
_g, _ = Symbolics.build_function(sgrad, x; expression = Val{false})
g = x -> vec(Matrix(T(_g(x))))
else
sgrad = Symbolics.jacobian([f(x)], x; simplify)
f_expr = Symbolics.build_function(sgrad, x)[1]
_g = eval(f_expr)
_g, _ = Symbolics.build_function(sgrad, x; expression = Val{false})
g = x -> vec(T(_g(x)))
end
if hessian
if sparse
shess = Symbolics.sparsejacobian(Base.invokelatest(g, x), x; simplify)
shess = Symbolics.sparsejacobian(g(x), x; simplify)
else
shess = Symbolics.jacobian(Base.invokelatest(g, x), x; simplify)
shess = Symbolics.jacobian(g(x), x; simplify)
end
h_expr = Symbolics.build_function(shess, x)[1]
_h = eval(h_expr)
_h, _ = Symbolics.build_function(shess, x; expression = Val{false})
h = x -> T(_h(x))
else
h = nothing
end
else
if sparse
sjac = Symbolics.sparsejacobian(f(x), x; simplify)
f_expr = Symbolics.build_function(sjac, x)[1]
_g = eval(f_expr)
_g, _ = Symbolics.build_function(sjac, x; expression = Val{false})
g = x -> Matrix(T(_g(x)))
else
sjac = Symbolics.jacobian(f(x), x; simplify)
f_expr = Symbolics.build_function(sjac, x)[1]
_g = eval(f_expr)
_g, _ = Symbolics.build_function(sjac, x; expression = Val{false})
g = x -> T(_g(x))
end
if hessian
if sparse
shess = Symbolics.sparsejacobian(vec(Base.invokelatest(g, x)), x; simplify)
shess = Symbolics.sparsejacobian(vec(g(x)), x; simplify)
else
shess = Symbolics.jacobian(vec(Base.invokelatest(g, x)), x; simplify)
shess = Symbolics.jacobian(vec(g(x)), x; simplify)
end
h_expr = Symbolics.build_function(shess, x)[1]
_h = eval(h_expr)
_h, _ = Symbolics.build_function(shess, x; expression = Val{false})
h = x -> reshape(T(_h(x)), length(val), N, N)
else
h = nothing
Expand Down
19 changes: 18 additions & 1 deletion test/symbolic.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
function _test_function_scoping()
model = Model()
addvar!(model, [0.0], [1.0])
set_objective!(model, x -> x[1])
add_eq_constraint!(model, x -> x[1])
return NonconvexIpopt.optimize(
symbolify(model),
IpoptAlg(),
[0.0];
options = IpoptOptions(),
)
end

@testset "SymbolicFunction" begin
@testset "Derivatives - simplify = $simplify, sparse = $sparse" for simplify in (false, true), sparse in (false, true)
f = SymbolicFunction(sum, rand(3); hessian = false, simplify, sparse)
Expand Down Expand Up @@ -30,6 +43,10 @@
sym_model = symbolify(m)
r = NonconvexIpopt.optimize(sym_model, alg, [1.234, 2.345], options = options)
@test abs(r.minimum - sqrt(8/27)) < 1e-6
@test norm(r.minimizer - [1/3, 8/27]) < 1e-6
@test norm(r.minimizer - [1/3, 8/27]) < 1e-6
end
@testset "function-scope" begin
r = _test_function_scoping()
@test abs(r.minimum) < 1e-6
end
end