# How to solve `no method matching real(::String)` when solving ODEs?

Hello,
I am simulating a microbial consortium (2 bacteria, 2 phages) but I get a MethodError during the solving step. Since I have duplicated items (two growth rates, two infection rates etc) I used vectors of 2 elements for each parameter. I think there is some problem in extracting numbers from these vectors. The implementation is:

``````function FUNK!(du, u, p, t)
μ = p[:μ]   # bacterial growth rate
κ = p[:κ]   # bacterial carrying capacity
ω = p[:ω]   # system wash-out rate
δ = p[:δ]   # phagial infection rate
η = p[:η]   # phagial lysis rate (inverse latency)
β = p[:β]   # phagial burst size
λ = p[:λ]   # phagial decay rate
#=
du = species A sensible
du = species A infected
du = phage a
du = species B sensible
du = species B infected
du = phage b
=#
N = u + u + u + u   # total bacteria
ρ = 1 - N/κ                     # logistic term
ϡ = (δ*u*u)            # upsampi: infected bacteria A
ς = (δ*u*u)            # varsigma: infected bacteria B

du = (μ*u*ρ)       - ϡ                     - (ω*u)
du =                       ϡ     - (η*u)   - (ω*u)
du = (η*β*u)    - ϡ     - (λ*u)   - (ω*u)

du = (μ*u*ρ)       - ς                     - (ω*u)
du =                       ς     - (η*u)   - (ω*u)
du = (η*β*u)    - ς     - (λ*u)   - (ω*u)
end
kappa   = 2.2e7             # carrying capacity (from Weitz)
omega   = 0.05              # outflow (from Weitz)
mu      = [0.16, 0.31]      # growth rate susceptible (pathogen)
beta    = [50.0, 75.0]      # burst size           (from Weitz)
delta   = [1e-9, 1e-9]      # adsorption rate (from Weitz)
eta     = [1, 1]            # reciprocal of latency   (from Weitz)
lambda  = [0, 0]            # decay rate in hours     (from Weitz)
x0      = [1e6, 1e5]        # initial bacterial density
v0      = [1e5, 1e4]        # initial phage population
i0      = [0, 0]            # initial infected population
r0      = [0, 0]            # initial resistant population
u0 = [x0, i0, r0, v0]  # S, I, R, V
parms = (μ=mu, κ=kappa, ω=omega, δ=delta, η=eta, β=beta, λ=lambda)
prob = ODEProblem(FUNK!, u0, (0.0, 1e4), parms)
soln = solve(prob, Rosenbrock23())

julia> soln = solve(prob, Rosenbrock23())
ERROR: MethodError: no method matching real(::String)
Closest candidates are:
real(::ChainRulesCore.AbstractThunk) at ~/.julia/packages/ChainRulesCore/GUvJT/src/tangent_types/thunks.jl:35
real(::Complex) at ~/src/julia/share/julia/base/complex.jl:72
real(::LinearAlgebra.Symmetric{var"#s859", S} where {var"#s859"<:Real, S<:(AbstractMatrix{<:var"#s859"})}) at ~/src/julia/share/julia/stdlib/v1.7/LinearAlgebra/src/symmetric.jl:353
...
``````

How can I solve the problem?
Thank you

PS:
what is the difference between [1, 2] and (1, 2)?

Arrays of arrays do not have vector semantics. Instead, use ComponentArrays.jl for this kind of nested model. Here’s an example:

``````using OrdinaryDiffEq, ComponentArrays

function FUNK!(du, u, p, t)
μ = p.μ   # bacterial growth rate
κ = p.κ   # bacterial carrying capacity
ω = p.ω   # system wash-out rate
δ = p.δ   # phagial infection rate
η = p.η   # phagial lysis rate (inverse latency)
β = p.β   # phagial burst size
λ = p.λ   # phagial decay rate
#=
du = species A sensible
du = species A infected
du = phage a
du = species B sensible
du = species B infected
du = phage b
=#
N = u + u + u + u   # total bacteria
ρ = 1 - N/κ                     # logistic term
ϡ = (δ*u*u)            # upsampi: infected bacteria A
ς = (δ*u*u)            # varsigma: infected bacteria B

du = (μ*u*ρ)       - ϡ                     - (ω*u)
du =                       ϡ     - (η*u)   - (ω*u)
du = (η*β*u)    - ϡ     - (λ*u)   - (ω*u)

du = (μ*u*ρ)       - ς                     - (ω*u)
du =                       ς     - (η*u)   - (ω*u)
du = (η*β*u)    - ς     - (λ*u)   - (ω*u)
end
kappa   = 2.2e7             # carrying capacity (from Weitz)
omega   = 0.05              # outflow (from Weitz)
mu      = [0.16, 0.31]      # growth rate susceptible (pathogen)
beta    = [50.0, 75.0]      # burst size           (from Weitz)
delta   = [1e-9, 1e-9]      # adsorption rate (from Weitz)
eta     = [1, 1]            # reciprocal of latency   (from Weitz)
lambda  = [0, 0]            # decay rate in hours     (from Weitz)
x0      = [1e6, 1e5]        # initial bacterial density
v0      = [1e5, 1e4]        # initial phage population
i0      = [0.0, 0]            # initial infected population
r0      = [0.0, 0]            # initial resistant population
u0 = ComponentArray(x=x0, i=i0, r=r0, v=v0)  # S, I, R, V
parms = ComponentArray(μ=mu, κ=kappa, ω=omega, δ=delta, η=eta, β=beta, λ=lambda)
prob = ODEProblem(FUNK!, u0, (0.0, 1e4), parms)
soln = solve(prob, Rosenbrock23())
``````

There are no ODEs on the v` terms though, so I assume something is missing from the model, but this solves.

1 Like

Thank you! I am getting problems with `u0` now. Only a subset of soln gives results, the other is simply a vector of 0s. Even if I use `u0 = [1e6, 0, 0, 1e4, 1e7, 0, 0, 1e3]` I get the same problem…

You have 8 variables but wrote ODEs for only 6.

1 Like