# Bug at solve method for Universall Differential Equations?

**URL:** https://discourse.julialang.org/t/bug-at-solve-method-for-universall-differential-equations/114566
**Category:** Machine Learning
**Tags:** sciml, componentarrays
**Created:** [May 22, 2024, 1:32pm UTC](https://discourse.julialang.org/t/bug-at-solve-method-for-universall-differential-equations/114566 "2024-05-22T13:32:40Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![Alergy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alergy/32/202344_2.png) [@Alergy](https://discourse.julialang.org/u/Alergy)
#### Post date: [May 22, 2024, 1:32pm UTC](https://discourse.julialang.org/t/bug-at-solve-method-for-universall-differential-equations/114566/1 "2024-05-22T13:32:40Z")

</div>

I am trying to somewhat emulate the [Universal Differential Equations tutorial](https://docs.sciml.ai/Overview/stable/showcase/missing_physics/), with a little twist. What I want to do is to learn the parameters of both a Differential Equation AND a Neural Network.

Here is the only code part I changed from the tutorial:

```julia
const U = Lux.Chain(Lux.Dense(2, 5, rbf), Lux.Dense(5, 5, rbf), Lux.Dense(5, 5, rbf),
              Lux.Dense(5, 2))
# Get the initial parameters and state variables of the model
p_nn, st = Lux.setup(rng, U)
const _st = st
# Concatenate DiffEq. params with NN params
p = [rand(rng, Float32,4); p_nn] # [α; β; γ; δ; p_nn] 

# Define the hybrid model
function ude_dynamics!(du, u, p, t)
    û = U(u, p[5], _st)[1] # Forward pass
    α, β, γ, δ = p[1:4]
    # Lokta-Volterra equations + ANN
    du[1] = α*u[1] - β*u[1]*u[2] + û[1]
    du[2] = γ*u[1]*u[2] - δ*u[2] + û[2]
end

# Define the problem
prob_nn = ODEProblem(ude_dynamics!, Xₙ[:, 1], tspan, p)

```

With this, I am able to evaluate predictions of the model (as `p[5] == p_nn`).

However, when I try to run the training with `Optimization.solve` I get the following error at [`OptimizationOptimisers.jl:59`](https://github.com/SciML/Optimization.jl/blob/523d61b929a574edcf7b02fab9d310e47155fd4e/lib/OptimizationOptimisers/src/OptimizationOptimisers.jl#L60):

```julia
ERROR: MethodError: no method matching real(::@NamedTuple{layer_1::@NamedTuple{…}, layer_2::@NamedTuple{…}, layer_3::@NamedTuple{…}, layer_4::@NamedTuple{…}})

```

It seems that `solve` is trying find the maximum value of the type of the parameters (Float32 in my case), using the `real` method in between in case the parameters are complex numers.

I tried to hack my way arround this by defining a dispatch that would return a Float32 number:

```julia
import Base: real
real(p::NamedTuple{T}) where T = 0f0

```

And then I got a quite informative error message telling me that I should be using a ComponentArray to define my parameter structure.

What would be the best way to do so?

---

<div class="post-metadata">

### Author: ![Alergy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alergy/32/202344_2.png) [@Alergy](https://discourse.julialang.org/u/Alergy)
#### Post date: [May 22, 2024, 2:07pm UTC](https://discourse.julialang.org/t/bug-at-solve-method-for-universall-differential-equations/114566/2 "2024-05-22T14:07:41Z")

</div>

The solution was actually quite simple, I just needed to define a ComponentArray with two fields:

```julia
p = ComponentArray(NN=p_nn, LV=rand(rng, Float32,4))

```
