# Mutating values in immutable struct (specifically of type ODESolution)

**URL:** <https://discourse.julialang.org/t/mutating-values-in-immutable-struct-specifically-of-type-odesolution/113760>\
**Category:** General Usage\
**Created:** [May 2, 2024, 8:45pm UTC](https://discourse.julialang.org/t/mutating-values-in-immutable-struct-specifically-of-type-odesolution/113760 "2024-05-02T20:45:19Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![hatmatrix](https://avatars.discourse-cdn.com/v4/letter/h/5f8ce5/32.png) [@hatmatrix](https://discourse.julialang.org/u/hatmatrix)\
**Post date:** [May 2, 2024, 8:45pm UTC](https://discourse.julialang.org/t/mutating-values-in-immutable-struct-specifically-of-type-odesolution/113760/1 "2024-05-02T20:45:20Z")

</div>

I’m solving a differential equation that has been nondimensionalized, so I’d like to change the scaling of the dependent variable for plotting. Here is my example.

```julia
using DifferentialEquations
using Plots
using Accessors

f(u, p, t) = 1.01 * u
u0 = 1 / 2
tspan = (0.0, 1.0)
prob = ODEProblem(f, u0, tspan)
sol = solve(prob, Tsit5(), reltol = 1e-8, abstol = 1e-8)

myscalingfactor = 1e2
@reset sol.t = sol.t .* myscalingfactor
plot(sol)

```

At the `@reset` statement, I get this error:

```julia
MethodError: no method matching ODESolution(::Vector{Float64}, ::Nothing, ::Nothing, ::Vector{Float64}, ::Vector{Vector{Float64}}, ::ODEProblem{Float64, Tuple{Float64, Float64}, false, SciMLBase.NullParameters, ODEFunction{false, SciMLBase.AutoSpecialize, typeof(f), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, @NamedTuple{}}, SciMLBase.StandardODEProblem}, ::Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, ::OrdinaryDiffEq.InterpolationData{ODEFunction{false, SciMLBase.AutoSpecialize, typeof(f), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Vector{Vector{Float64}}, OrdinaryDiffEq.Tsit5ConstantCache}, ::Bool, ::Int64, ::DiffEqBase.DEStats, ::Nothing, ::SciMLBase.ReturnCode.T)

```

I see [this solution](https://discourse.julialang.org/t/i-dont-see-any-caveats-in-setfield-jl-accessors-jl-but-im-getting-a-method/54657/3), but I’m not sure how to define a constructor for the complicated structure above and why it doesn’t exist in the first place if it was created by `solve`?

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [May 2, 2024, 9:09pm UTC](https://discourse.julialang.org/t/mutating-values-in-immutable-struct-specifically-of-type-odesolution/113760/2 "2024-05-02T21:09:42Z")

</div>

The `ODESolution` itself appears to be a very big and complicated structure. It probably has a nontrivial custom constructor and `Accessors.jl` has not been told how to use it.

Even if `ODESolution` itself is immutable, a `Vector` _(almost?) anywhere_ is still mutable. You can simply do `sol.t .*= myscalingfactor` in this case. Recall, this is identical to `sol.t .= sol.t .* myscalingfactor`. The `.=` is why this works to update `sol.t` in-place – no need to make a new `Vector` and build a new `ODESolution` around it.

Hopefully there isn’t some dependence on this field baked into other fields. If there is, you could end up with a `ODESolution` that does not behave as expected.

---

<div class="post-metadata">

**Author:** ![hatmatrix](https://avatars.discourse-cdn.com/v4/letter/h/5f8ce5/32.png) [@hatmatrix](https://discourse.julialang.org/u/hatmatrix)\
**Post date:** [May 2, 2024, 10:27pm UTC](https://discourse.julialang.org/t/mutating-values-in-immutable-struct-specifically-of-type-odesolution/113760/3 "2024-05-02T22:27:12Z")

</div>

Interesting idea… so you update the elements of the vector and not the property with a new vector.

> Hopefully there isn’t some dependence on this field baked into other fields.

…unfortunately it looks to be the case.

Plotting

```julia
plot(sol.t .* myscalingfactor, sol.u)

```

gives me

![plot1](https://global.discourse-cdn.com/julialang/original/3X/d/8/d8be0c252f944eb10ad540f78efd5aa362134706.png)

while

```julia
sol.t .*= myscalingfactor
plot(sol)

```

gives me

![plot2](https://global.discourse-cdn.com/julialang/original/3X/3/5/35d817ea856dc5d1585b0f47e74d4a1d8e031319.png)

However this appears to due to the internals for the plot method for `ODESolution`. The command below gives the expected curve (like the first plot above) after the vector modification.

```julia
plot(sol.t, sol.u)

```

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [May 2, 2024, 10:51pm UTC](https://discourse.julialang.org/t/mutating-values-in-immutable-struct-specifically-of-type-odesolution/113760/4 "2024-05-02T22:51:30Z")

</div>

For what it’s worth, the `@reset` thing might not update the vector properly either. But it looks like you’ll have to do something more clever here if you want to fix the value in post-processing like this.

---

<div class="post-metadata">

**Author:** ![hatmatrix](https://avatars.discourse-cdn.com/v4/letter/h/5f8ce5/32.png) [@hatmatrix](https://discourse.julialang.org/u/hatmatrix)\
**Post date:** [May 3, 2024, 2:49am UTC](https://discourse.julialang.org/t/mutating-values-in-immutable-struct-specifically-of-type-odesolution/113760/5 "2024-05-03T02:49:31Z")

</div>

Thanks - I guess that’s a separate issue to be resolved for that specific method.
