Skip to content

Commit

Permalink
Merge pull request #31 from x3042/lump-matrix
Browse files Browse the repository at this point in the history
Remember the lumping matrix
  • Loading branch information
sumiya11 authored Feb 16, 2024
2 parents b8bdfec + 311f5fb commit 579cb70
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 5 deletions.
22 changes: 22 additions & 0 deletions src/ExactODEReduction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,28 @@ function find_reductions(
ChainOfReductions(results)
end

function find_conservation_laws(system::ODE{P}; seed=nothing, loglevel=Logging.Info) where {P}
prev_logger = Logging.global_logger(ConsoleLogger(stderr, loglevel))

isnothing(seed) && (seed = getnewrandomseed())
Random.seed!(seed)
@info "Global random seed: $seed"

eqs = equations_extended(system)

basis, kerdim, ker, relations = constant_linear_relations(eqs)
_relations_sym = ker * basis
relations_sym = [_relations_sym[i, :] for i in 1:kerdim]

Logging.global_logger(prev_logger)

laws = []
for i in 1:kerdim
push!(laws, (basis=basis, matrix=relations[i], law=relations_sym[i]))
end
laws
end

export ODE, @ODEsystem, equations, vars
export states, parameters, initial_conditions, parameter_values
export set_parameter_values, to_state, to_parameter
Expand Down
15 changes: 11 additions & 4 deletions src/Reduction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,21 @@ struct Reduction{A, B, C}
new_system::ODE{A}
new_vars::Dict{A, B}
old_system::ODE{C}
lumping_matrix::Union{Nothing, Matrix{Any}}

function Reduction{A, B, C}(new_system::ODE{A}, new_vars::Dict{A, B}, old_system::ODE{C}) where {A, B, C}
return new{A, B, C}(new_system, new_vars, old_system)
lumping_matrix = nothing
if !isempty(new_vars)
lumping_vars = [new_vars[x] for x in gens(parent(new_system))]
lumping_combs = [sum(collect(coefficients(comb)) .* exponent_vectors(comb)) for comb in lumping_vars]
lumping_matrix = mapreduce(permutedims, vcat, lumping_combs)
end
return new{A, B, C}(new_system, new_vars, old_system, lumping_matrix)
end

function Reduction{P}(old_ode::ODE{P}, subspace, parameter_strategy=:inhertiance) where {P}
(transformation, new_equations) = perform_change_of_variables(equations_extended(old_ode), subspace)

(lumping_matrix, transformation, new_equations) = perform_change_of_variables(equations_extended(old_ode), subspace)
# (!) assumes the correct order in new_equations, i.e.,
# ∂y[1] ~ new_equations[1],
# ∂y[2] ~ new_equations[2],
Expand Down Expand Up @@ -82,7 +89,7 @@ struct Reduction{A, B, C}
@warn "Unknown parameter handling strategy $parameter_strategy, using none"
end

return new{elem_type(parent(new_ode)), elem_type(parent(first(transformation))), elem_type(parent(old_ode))}(new_ode, new_vars, old_ode)
return new{elem_type(parent(new_ode)), elem_type(parent(first(transformation))), elem_type(parent(old_ode))}(new_ode, new_vars, old_ode, lumping_matrix)
end
end

Expand Down
21 changes: 21 additions & 0 deletions src/linalg_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,24 @@ function construct_jacobians(system)
ring = parent(first(keys(system)))
construct_jacobians([system[x] for x in gens(ring)])
end

#------------------------------------------------------------------------------

# Find the left kernel of a Macaulay matrix of `system`.
function constant_linear_relations(system::AbstractArray{T}) where {T<:Nemo.MPolyElem}
domain = base_ring(first(system))
poly_ring = parent(first(system))
m = length(system)
labels = unique(sort(reduce(vcat, map(collect monomials, system)), rev=true))
n = length(labels)
S = Nemo.MatrixSpace(domain, m, n)
A = zero(S)
for (p_idx, poly) in enumerate(system)
for (l_idx, label) in enumerate(labels)
A[p_idx, l_idx] = coeff(poly, label)
end
end
kerdim, ker = Nemo.left_kernel(A)
relations = [ker[i, :] for i in 1:kerdim]
gens(poly_ring), kerdim, ker, relations
end
2 changes: 1 addition & 1 deletion src/parametrization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function perform_change_of_variables(system, invariants; new_vars_name="y")

newsystem = [Nemo.evaluate(p, substitutions) for p in newsystem]

return (transform, newsystem)
return (Matrix(transform_matrix), transform, newsystem)
end

"""
Expand Down

0 comments on commit 579cb70

Please sign in to comment.