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

Homotopy Continuation extension and remake #683

Merged
merged 31 commits into from
Oct 4, 2023
Merged

Homotopy Continuation extension and remake #683

merged 31 commits into from
Oct 4, 2023

Conversation

TorkelE
Copy link
Member

@TorkelE TorkelE commented Sep 19, 2023

With the introduction of package extensions (https://pkgdocs.julialang.org/dev/creating-packages/#Conditional-loading-of-code-in-packages-(Extensions)) we can add some additional support for packages like HomotopyContinuation without making incompatibilities messier.

This introduces a single function, hc_steady_states which finds the steady states of a reaction system using homotopy continuation. If initial conditions are provided, conservation laws are automatically utilised. This feature is stored in a new "HomotopyContinuationExtension" extension, and only available if HomoyopyContinuation is loaded.

This is the full docstring of the new function:
hc_steady_states(rs::ReactionSystem, ps; filter_negative=true, neg_thres=-1e-20, u0=typeof(ps)(), kwargs...)

Uses homotopy continuation to find the steady states of the ODE system corresponding to the provided reaction system.

Arguments:

  • rs::ReactionSystem: The reaction system for which we want to find the steady states.
  • ps: The parameter values for which we want to find the steady states.
  • filter_negative=true: If set to true, solutions with any species concentration <0 is removed from the output.
  • neg_thres=-1e-20: Determine the minimum values for which a species concentration is to be considred non-negative. Species conentrations > neg_thres but < 0.0 are set to 0.0.
  • u0=typeof(ps)(): Initial conditions for which we want to find the steady states. For systems with conservation laws this are required to compute conserved quantities.
  • kwargs...: any additional arguments (like show_progress= true) are passed into HomotopyContinuation.jl's solve call.

Examples:

rs = @reaction_network begin
    k1, Y --> 2X
    k2, 2X --> X + Y
    k3, X + Y --> Y
    k4, X --> 0
end
ps = [:k3 => 1.0, :k2 => 2.0, :k4 => 1.5, :k1=>8.0]
hc_sol = hc_steady_states(rs, ps)

gives

[0.5000000000000002, 2.0000000000000004]
[0.0, 0.0]
[4.499999999999999, 5.999999999999999]

Notes:

  • This is a wrapper around the solve function provided by HomotopyContinuation.jl, all credit for this functionality to that package's authors.

@ChrisRackauckas
Copy link
Member

I do think that the specialization here should be able to be removed when it becomes a standard NonlinearSolve solver. Though I don't know what the time line on that will be.

@TorkelE
Copy link
Member Author

TorkelE commented Sep 19, 2023

When that happens we shoudl be able to just delete the extension, but in the meantime this should be good.

@TorkelE TorkelE changed the title Homotopy Continuation extension and remakr Homotopy Continuation extension and remake Sep 20, 2023
@isaacsas
Copy link
Member

CI is still failing?

@isaacsas
Copy link
Member

A test failed.

@TorkelE
Copy link
Member Author

TorkelE commented Sep 25, 2023

You mean this one:
image
it is for Julia 1.6 though, right?

I will try to check what is going on and return back, but if it is failing on 1.6 and not the latest version (if my interpretation is correct), it might be a mess to sort out, especially if the problem is in HC. Either case, will try to figure out what it is.

@isaacsas
Copy link
Member

SciML is still supporting 1.6 till the next LTS release, so we need to figure out the issue. If it is HC we should open an issue for them to fix it.

@TorkelE
Copy link
Member Author

TorkelE commented Sep 25, 2023

ok

@TorkelE
Copy link
Member Author

TorkelE commented Sep 25, 2023

I think I know it. 1.6 does not support extension, hence this not working. This kind of defeats the entire purpose of this PR. Ideally I would go ahead anyway, but https://pkgdocs.julialang.org/v1/creating-packages/#Transition-from-normal-dependency-to-extension seems like an OK workaround so will go with that (hopefully being able to revert it at some point.

test/runtests.jl Outdated Show resolved Hide resolved
Copy link
Member

@isaacsas isaacsas left a comment

Choose a reason for hiding this comment

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

I think those are all my comments if you want to make updates.

TorkelE and others added 15 commits October 3, 2023 19:03
Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
…n_extension.jl

Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
…n_extension.jl

Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
…n_extension.jl

Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
…n_extension.jl

Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
…n_extension.jl

Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
…n_extension.jl

Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
…n_extension.jl

Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
…n_extension.jl

Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
@TorkelE
Copy link
Member Author

TorkelE commented Oct 4, 2023

Added your changes, except for a few that feel more like long-term questions regarding symbolic function handling. Also let u0 default to nothing and didn't use the subset check regarding conservation laws, see comments.

steady_state_stability(s_states::Vector{Float64}, ps, rs::ReactionSystem) = steady_state_stability(s_states, ODEFunction(convert(ODESystem, rs); jac=true))
# If a ODESystem is given directyl, no conversion is needed.
function steady_state_stability(s_states::Vector{Float64}, ps, ofun::ODEFunction)
maximum(eigen(ofun.jac(ss, last.(ps), Inf)).values) < 0.0
Copy link
Member

Choose a reason for hiding this comment

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

You need to look at the real part of the eigenvalues as they can be complex. Also, a system may not be unstable if the real parts are all non-negative (i.e. some are zero), so we probably shouldn't return a boolean but an enum that indicates, stable, unstable, eigenvalues are non-negative with at least one zero.

Maybe this can be moved to a future PR when we can better work out how to do this (and so we can get this merged now)?

# For a given reaction system, paraemter values, and initial conditions, find the polynomial that HC solves to find steady states.
function steady_state_polynomial(rs::ReactionSystem, ps, u0)
ns = convert(NonlinearSystem, rs; remove_conserved = true)
pre_varmap = map(pair -> pair, [symmap_to_varmap(rs,u0); symmap_to_varmap(rs,ps)])
Copy link
Member

Choose a reason for hiding this comment

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

Do you have a test that this all works if the user passes a tuple for the parameter map using mixed types like integers and floats (even if the u0 map is a vector)?

@TorkelE
Copy link
Member Author

TorkelE commented Oct 4, 2023

  • stability computation removed.
  • Added Tuple with mixed int/float to tests.
  • Now combines p/u0 using:
[symmap_to_varmap(rs,u0)..., symmap_to_varmap(rs,ps)...]

(I tried other stuff, but couldn't come up with something that worked well on this combination which didn't require more lines of code. Given what we are doing next, I presume that the performance damage will be relatively minimal, and I didn't want to reduce readability.

  • Now uses this check:
any(s -> s in vars_with_vals, species(rs))

I think part of the problem with your suggestion was that you required initial conditions for all species, while I only want to require for some. This way when you have a system with many species and a single conserved quantity you don't have to provide tons of initial conditions. I have also pointed this out in docs properly.

@TorkelE TorkelE merged commit 5d53ae2 into master Oct 4, 2023
8 of 9 checks passed
@TorkelE TorkelE deleted the hc_extension branch June 8, 2024 18:32
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.

3 participants