# ModelingToolkit and normalize()

**URL:** <https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349>\
**Category:** General Usage\
**Tags:** question, package, modelingtoolkit\
**Created:** [December 8, 2023, 9:58pm UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349 "2023-12-08T21:58:43Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [December 8, 2023, 9:58pm UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/1 "2023-12-08T21:58:43Z")

</div>

The following code fails:

```julia
using ModelingToolkit, OrdinaryDiffEq, PyPlot, LinearAlgebra

G_EARTH = Float64[0.0, 0.0, -9.81] # gravitational acceleration

# model
@parameters mass=1.0 c_spring=50.0 damping=0.5 l0=10.0
@variables t pos(t)[1:3]=[0.0, 0.0, 0.0]
@variables vel(t)[1:3]=[0.0, 0.0, 50.0] 
@variables acc(t)[1:3]=[0.0, 0.0, -9.81]
@variables unit_vector(t)[1:3]=[1.0, 0.0, 0.0]
@variables force(t) = 0.0 norm1(t) = l0
D = Differential(t)

eqs = vcat(D.(pos) ~ vel,
           D.(vel) ~ acc,
           norm1 ~ norm(pos),
           unit_vector ~ normalize(pos),
           force ~ norm1 * c_spring,
           acc .~ G_EARTH)

@named sys = ODESystem(eqs, t)

```

with the message:

```julia
ERROR: LoadError: TypeError: non-boolean (Num) used in boolean context
Stacktrace:
 [1] copyto!(dest::OffsetArrays.OffsetVector{Num, Vector{Num}}, src::Symbolics.Arr{Num, 1})
   @ Base ./abstractarray.jl:1059
 [2] copymutable_oftype(A::Symbolics.Arr{Num, 1}, ::Type{Num})
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.0-rc2+0.x64.linux.gnu/share/julia/stdlib/v1.10/LinearAlgebra/src/LinearAlgebra.jl:404
 [3] normalize(a::Symbolics.Arr{Num, 1}, p::Int64)
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.0-rc2+0.x64.linux.gnu/share/julia/stdlib/v1.10/LinearAlgebra/src/generic.jl:1881
 [4] normalize(a::Symbolics.Arr{Num, 1})
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.0-rc2+0.x64.linux.gnu/share/julia/stdlib/v1.10/LinearAlgebra/src/generic.jl:1879
 [5] top-level scope
   @ ~/repos/Tethers.jl/src/Tether_03.jl:15
 [6] include
   @ ./client.jl:489 [inlined]
 [7] macro expansion
   @ ./timing.jl:279 [inlined]
 [8] top-level scope
   @ ./REPL[1]:1
in expression starting at /home/ufechner/repos/Tethers.jl/src/Tether_03.jl:15

```

It works if I comment the line:

```julia
 unit_vector ~ normalize(pos),

```

What is the best way to solve this issue?

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [December 9, 2023, 5:35am UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/2 "2023-12-09T05:35:13Z")

</div>

You could replace `normalize` with `pos ./ norm(pos)` to get rid of the error.

The problem seems to be that `isempty(::Symbolics.Arr{Num,1})` or in your case `isempty(pos)` (which is called inside `normalize`) returns a `Num` instead of a `Bool`. Not sure if that is a feature or a bug, I suspect it is a feature for other aspects.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [December 9, 2023, 11:48am UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/3 "2023-12-09T11:48:36Z")

</div>

Created a bug report: [normalize() fails with symbolic arguments · Issue #52465 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/52465)

Not sure if it is a bug in LinearAlgebra or in ModelingToolkit, though…

Extra question:  
The term `pos / norm(pos)` works as good as your suggestion, `pos ./ norm(pos)`.

When is the dot operator needed and when not?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 9, 2023, 2:21pm UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/4 "2023-12-09T14:21:50Z")

</div>

It’s not a registered function, so it may need to wait until symbolic array registration merges (which is hopefully next week) to then be held lazy.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [December 9, 2023, 2:27pm UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/5 "2023-12-09T14:27:51Z")

</div>

> [@ChrisRackauckas](#):
>
> it may need to wait until symbolic array registration merges

Merges to which package, or to Julia itself?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 9, 2023, 2:29pm UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/6 "2023-12-09T14:29:52Z")

</div>

Symbolics.jl. The PR is done but just missing tests.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [December 16, 2023, 6:46am UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/7 "2023-12-16T06:46:31Z")

</div>

It still crashes:

```julia
using ModelingToolkit, LinearAlgebra

@variables t pos(t)[1:3] = [0.0, 0.0, 10.0]
normalize(pos)

```

with:

```julia
julia> normalize(pos)
ERROR: TypeError: non-boolean (Num) used in boolean context
Stacktrace:
 [1] copyto!(dest::OffsetArrays.OffsetVector{Num, Vector{Num}}, src::Symbolics.Arr{Num, 1})
   @ Base ./abstractarray.jl:1059
 [2] copymutable_oftype(A::Symbolics.Arr{Num, 1}, ::Type{Num})
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.0-rc2+0.x64.linux.gnu/share/julia/stdlib/v1.10/LinearAlgebra/src/LinearAlgebra.jl:404
 [3] normalize(a::Symbolics.Arr{Num, 1}, p::Int64)
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.0-rc2+0.x64.linux.gnu/share/julia/stdlib/v1.10/LinearAlgebra/src/generic.jl:1881
 [4] normalize(a::Symbolics.Arr{Num, 1})
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.0-rc2+0.x64.linux.gnu/share/julia/stdlib/v1.10/LinearAlgebra/src/generic.jl:1879
 [5] top-level scope
   @ REPL[8]:1

```

```julia
(Mo) pkg> st
Status `~/repos/Mo/Project.toml`
  [961ee093] ModelingToolkit v8.74.0
  [0c5d862f] Symbolics v5.13.0

```

Shall I create a bug report for Modelingtoolkit?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 16, 2023, 1:04pm UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/8 "2023-12-16T13:04:31Z")

</div>

Did you try registering it?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [December 16, 2023, 1:07pm UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/9 "2023-12-16T13:07:07Z")

</div>

I do not understand what you mean… What shall I register, and how?

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [December 16, 2023, 2:05pm UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/10 "2023-12-16T14:05:52Z")

</div>

From docs I think: `@register_symbolic f_fun(t)`

> **[Getting Started with ModelingToolkit.jl · ModelingToolkit.jl](https://docs.sciml.ai/ModelingToolkit/stable/tutorials/ode_modeling/)**
>
> Documentation for ModelingToolkit.jl.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [December 16, 2023, 9:46pm UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/11 "2023-12-16T21:46:25Z")

</div>

Not working:

```julia
using ModelingToolkit, LinearAlgebra

@variables t pos(t)[1:3] = [0.0, 0.0, 10.0]

@register_symbolic LinearAlgebra.normalize(pos)

normalize(pos)

```

Message:

```julia
ERROR: LoadError: TypeError: non-boolean (Num) used in boolean context
Stacktrace:
 [1] copyto!(dest::OffsetArrays.OffsetVector{Num, Vector{Num}}, src::Symbolics.Arr{Num, 1})
   @ Base ./abstractarray.jl:1059
 [2] copymutable_oftype(A::Symbolics.Arr{Num, 1}, ::Type{Num})
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.0-rc2+0.x64.linux.gnu/share/julia/stdlib/v1.10/LinearAlgebra/src/LinearAlgebra.jl:404
 [3] normalize(a::Symbolics.Arr{Num, 1}, p::Int64)
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.0-rc2+0.x64.linux.gnu/share/julia/stdlib/v1.10/LinearAlgebra/src/generic.jl:1881
 [4] normalize(a::Symbolics.Arr{Num, 1})
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.0-rc2+0.x64.linux.gnu/share/julia/stdlib/v1.10/LinearAlgebra/src/generic.jl:1879
 [5] top-level scope
   @ ~/repos/Tethers.jl/mwes/mwe01.jl:11
 [6] include(fname::String)
   @ Base.MainInclude ./client.jl:489
 [7] top-level scope
   @ REPL[1]:1
in expression starting at /home/ufechner/repos/Tethers.jl/mwes/mwe01.jl:11

```

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [December 17, 2023, 1:18am UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/12 "2023-12-17T01:18:59Z")

</div>

Is this any help:

```julia
julia> using Symbolics

julia> @variables t pos(t)[1:3]
2-element Vector{Any}:
 t
  (pos(t))[1:3]

julia> using LinearAlgebra

julia> @register_symbolic LinearAlgebra.normalize(v::AbstractArray, p::Real)

julia> normalize(pos)
LinearAlgebra.normalize(pos(t), 2)

```

?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 17, 2023, 3:08am UTC](https://discourse.julialang.org/t/modelingtoolkit-and-normalize/107349/13 "2023-12-17T03:08:20Z")

</div>

I thought you were linking to the new `@register_array_symbolic` PR which is why you asked this the day after it merged? That gives the tool to register the array function `normalize` but someone needs to add it to the list of registered functions for it to be kept lazy.
