Skip to content

Conversation

ParasPuneetSingh
Copy link
Collaborator

Checklist

  • Appropriate tests were added
  • Any code changes were done in a way that does not break public API
  • All documentation related to code changes were updated
  • The new code follows the
    contributor guidelines, in particular the SciML Style Guide and
    COLPRAC.
  • Any new documentation only uses public API

Additional context

Add any other context about the problem here.

Comment on lines 66 to 81
function solve_constrained_root(cache, u0, p)
n = length(u0)
cons_vals = cache.f.cons(u0, p)
m = length(cons_vals)
function resid!(res, u)
temp = similar(u)
f_mass!(temp, u, p, 0.0)
res .= temp
end
u0_ext = vcat(u0, zeros(m))
prob_nl = NonlinearProblem(resid!, u0_ext, p)
sol_nl = solve(prob_nl, Newton(); tol = 1e-8, maxiters = 100000,
callback = cache.callback, progress = get(cache.solver_args, :progress, false))
u_ext = sol_nl.u
return u_ext[1:n], sol_nl.retcode
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's this about?

Comment on lines 113 to 62
function finite_difference_jacobian(f, x; ϵ = 1e-8)
n = length(x)
fx = f(x)
if fx === nothing
return zeros(eltype(x), 0, n)
elseif isa(fx, Number)
J = zeros(eltype(fx), 1, n)
for j in 1:n
xj = copy(x)
xj[j] += ϵ
diff = f(xj)
if diff === nothing
diffval = zero(eltype(fx))
else
diffval = diff - fx
end
J[1, j] = diffval / ϵ
end
return J
else
m = length(fx)
J = zeros(eltype(fx), m, n)
for j in 1:n
xj = copy(x)
xj[j] += ϵ
fxj = f(xj)
if fxj === nothing
@inbounds for i in 1:m
J[i, j] = -fx[i] / ϵ
end
else
@inbounds for i in 1:m
J[i, j] = (fxj[i] - fx[i]) / ϵ
end
end
end
return J
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary

if solver_method == :mass_matrix
return solve_dae_mass_matrix(cache, dt, maxit, u0, p)
else
return solve_dae_indexing(cache, dt, maxit, u0, p, differential_vars)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you mean implicit?

Comment on lines 166 to 167
solver_method = get_solver_type(cache.opt)
if solver_method == :mass_matrix
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual check is alg isa DAEAlgorithm which means implicit, otherwise mass matrix

end

if m == 0
optf = ODEFunction(f_mass!, mass_matrix = I(n))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
optf = ODEFunction(f_mass!, mass_matrix = I(n))
optf = ODEFunction(f_mass!)

if m == 0
optf = ODEFunction(f_mass!, mass_matrix = I(n))
prob = ODEProblem(optf, u0, (0.0, 1.0), p)
return solve(prob, HighOrderDescent(); dt=dt, maxiters=maxit)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is the solver being specified?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when falling back to ode, I thought it better to use the best method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not necessarily the best method.

n = length(u0)
m = length(cons_vals)
u0_extended = vcat(u0, zeros(m))
M = zeros(n + m, n + m)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just make M a diagonal matrix

Comment on lines 246 to 168
function f_mass!(du, u, p_, t)
x = @view u[1:n]
λ = @view u[n+1:end]
grad_f = similar(x)
if cache.f.grad !== nothing
cache.f.grad(grad_f, x, p_)
else
grad_f .= ForwardDiff.gradient(z -> cache.f.f(z, p_), x)
end
J = Matrix{eltype(x)}(undef, m, n)
if cache.f.cons_j !== nothing
cache.f.cons_j(J, x)
else
J .= finite_difference_jacobian(z -> cache.f.cons(z, p_), x)
end
@. du[1:n] = -grad_f - (J' * λ)
consv = cache.f.cons(x, p_)
if consv === nothing
fill!(du[n+1:end], zero(eltype(x)))
else
if isa(consv, Number)
@assert m == 1
du[n+1] = consv
else
@assert length(consv) == m
@. du[n+1:end] = consv
end
end
return nothing
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary, it's just 0

Comment on lines 330 to 225
if cache.f.cons_j !== nothing
cache.f.cons_j(J, x)
else
J .= finite_difference_jacobian(z -> cache.f.cons(z,p_), x)
end
@. res[1:n] = du_x + grad_f + J' * λ
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just zero = cons for the other terms.

Comment on lines 67 to 71
if opt.solver isa Union{Rodas5, RadauIIA5, ImplicitEuler, Trapezoid}
return :mass_matrix
else
return :indexing
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use opt.solver isa DAEAlgorithm instead

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been removed in the latest commits.

ParasPuneetSingh and others added 18 commits September 17, 2025 10:25
Docs for first draft of OptimizationODE.jl
Method descriptions for the solvers added.
Updated docs.
updated docs
Removed redundant functions, used proper jacobian.
Jacobian fix for tests.
Removed hard coded alg call.
Linear Algebra dependency added.
added package dependencies
Removed redundant tests.
Mismatch on problem and algorithm fixed.
Correcting function definition.
@ChrisRackauckas ChrisRackauckas merged commit 6a31496 into SciML:master Sep 17, 2025
40 of 71 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants