# Trouble with writing a mutable struct with MVector fields

**URL:** https://discourse.julialang.org/t/trouble-with-writing-a-mutable-struct-with-mvector-fields/53135
**Category:** New to Julia
**Created:** [January 11, 2021, 3:12am UTC](https://discourse.julialang.org/t/trouble-with-writing-a-mutable-struct-with-mvector-fields/53135 "2021-01-11T03:12:28Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![GrantHecht](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/granthecht/32/20898_2.png) [@GrantHecht](https://discourse.julialang.org/u/GrantHecht)
#### Post date: [January 11, 2021, 3:12am UTC](https://discourse.julialang.org/t/trouble-with-writing-a-mutable-struct-with-mvector-fields/53135/1 "2021-01-11T03:12:28Z")

</div>

I’m working on implementing a Particle Swarm Optimization routine in Julia and would like to define a “Particle” mutable struct with MVector fields (from StaticArrays.jl) but am running into some issues.

Here is my current struct:

```julia
mutable struct Particle{M,T} where {M <: Integer, T <: AbstractFloat}

    x::MVector{M,T} # Current Position
    v::MVector{M,T} # Current Velocity
    p::MVector{M,T} # Best Position

    fx::T # Current Objective Function Value
    fp::T # Best Objective Function Value

    function Particle(x::MVector{M,T}, v::MVector{M,T}) where {M <: Integer, T <: AbstractFloat}
        xl = length(x)
        vl = length(v)
        if xl != vl
            throw(ArgumentError("Particle's position and velocity must be the same length."))
        else
            new{M,T}(x, v, NaN*similar(x), NaN*x[1], NaN*x[1])
        end
    end
end

```

Using my defined constructor, I get the following error:

```julia
julia> a = MVector{3}(rand(3))
3-element MArray{Tuple{3},Float64,1,3} with indices SOneTo(3):
 0.6821892643778722
 0.41842430858799906

julia> b = MVector{3}(rand(3))
3-element MArray{Tuple{3},Float64,1,3} with indices SOneTo(3):
 0.9403860675524811
 0.163642437664691
 0.1349743741370517

julia> Particle(a,b)
ERROR: MethodError: no method matching Particle(::MArray{Tuple{3},Float64,1,3}, ::MArray{Tuple{3},Float64,1,3})
Stacktrace:
 [1] top-level scope at REPL[3]:1

```

I’ve primarily used MATLAB for all of my work and am relatively new to Julia and this error has me stumped. What confuses me most is, upon running the following command:

```julia
julia> methods(Particle)
# 1 method for type constructor:
[1] (::Type{Particle})(x::MArray{Tuple{M},T,1,M}, v::MArray{Tuple{M},T,1,M}) where {M<:Integer, T<:AbstractFloat} in Main at c:\Users\grant\.julia\dev\JuSwarm\src\particle.jl:36

```

it appears (to the best of my knowledge) that the correct method for constructing my Particle type does exist… Any and all help on this issue would be greatly appreciated!

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [January 11, 2021, 3:40am UTC](https://discourse.julialang.org/t/trouble-with-writing-a-mutable-struct-with-mvector-fields/53135/2 "2021-01-11T03:40:47Z")

</div>

I am not 100% sure but I think the problem is a subtle one.

Basically, your type restrictions are wrong. `M <: Integer` means a **type** `M` that is a subtype of `Integer`. `3` is no type, it is a value.

```julia
julia> 3 <: Integer
ERROR: TypeError: in <:, expected Type, got a value of type Int64
Stacktrace:
 [1] top-level scope at REPL[7]:1

```

If you remove the type restriction (the `<: Integer` bit) from both `where` clauses (on the `struct` and on the constructor), then the problem disappears.

Also, you do not need that test with the lengths. You are matching the `M` values of both `x` and `v` `MVector`s in the signature, it will already error if your try to pass two `MVector`s of different lengths (as the length is encoded in the type).

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [January 11, 2021, 1:09pm UTC](https://discourse.julialang.org/t/trouble-with-writing-a-mutable-struct-with-mvector-fields/53135/3 "2021-01-11T13:09:41Z")

</div>

Also, I forgot to say before: Welcome to our community! 🎊

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [January 11, 2021, 2:04pm UTC](https://discourse.julialang.org/t/trouble-with-writing-a-mutable-struct-with-mvector-fields/53135/4 "2021-01-11T14:04:29Z")

</div>

Here (Julia 1.5.3) I cannot define the struct as you did:

```julia
julia> mutable struct Particle{M,T} where {M <: Integer, T <: AbstractFloat}
         x::MVector{M,T} # Current Position
         v::MVector{M,T} # Current Velocity
       end
ERROR: syntax: invalid type signature around REPL[24]:1
Stacktrace:
 [1] top-level scope at REPL[24]:1

```

(that is not a good error message, clearly)

Anyway, as mentioned above, removing most of the restrictions works:

```julia
julia> mutable struct Particle{M,T}
         x::MVector{M,T} # Current Position
         v::MVector{M,T} # Current Velocity
       end

julia> Particle(x::MVector{M,T}) where {M,T} = Particle(x,x)
Particle

julia> x = rand(MVector{3,Float64})
3-element MArray{Tuple{3},Float64,1,3} with indices SOneTo(3):
 0.2803399080247968
 0.11607884285749992
 0.6952047979171718

julia> Particle(x)
Particle{3,Float64}([0.2803399080247968, 0.11607884285749992, 0.6952047979171718], [0.2803399080247968, 0.11607884285749992, 0.6952047979171718])

```

And note that the final `Particle` is completely type-specific, as you want.

One additional thing: you may not need (want) mutable static arrays. You can work with immutable static arrays, and mutate the fields of your mutable structs.

```julia
julia> using StaticArrays

julia> mutable struct Particle{M,T}
         x::SVector{M,T} # Current Position
         v::SVector{M,T} # Current Velocity
       end

julia> p = Particle(rand(SVector{3,Float64}),rand(SVector{3,Float64}))
Particle{3,Float64}([0.9743653173834737, 0.3775182744632197, 0.37405647923023433], [0.5096490765009536, 0.530903496717793, 0.1187232054938756])

julia> y = SVector{3,Float64}(0., 0., 0.)
3-element SArray{Tuple{3},Float64,1,3} with indices SOneTo(3):
 0.0
 0.0
 0.0

julia> p.x = y
3-element SArray{Tuple{3},Float64,1,3} with indices SOneTo(3):
 0.0
 0.0
 0.0

julia> p
Particle{3,Float64}([0.0, 0.0, 0.0], [0.5096490765009536, 0.530903496717793, 0.1187232054938756])

```

(this mutation is allocation-free, and fast)

---

<div class="post-metadata">

### Author: ![GrantHecht](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/granthecht/32/20898_2.png) [@GrantHecht](https://discourse.julialang.org/u/GrantHecht)
#### Post date: [January 11, 2021, 2:15pm UTC](https://discourse.julialang.org/t/trouble-with-writing-a-mutable-struct-with-mvector-fields/53135/5 "2021-01-11T14:15:23Z")

</div>

Thank you for the quick reply!

Just removing the `<: Integer` type restriction still resulted in an error but removing both type restrictions as [leandromartinez98](https://discourse.julialang.org/u/leandromartinez98) suggested solved my issues.

---

<div class="post-metadata">

### Author: ![GrantHecht](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/granthecht/32/20898_2.png) [@GrantHecht](https://discourse.julialang.org/u/GrantHecht)
#### Post date: [January 11, 2021, 2:15pm UTC](https://discourse.julialang.org/t/trouble-with-writing-a-mutable-struct-with-mvector-fields/53135/6 "2021-01-11T14:15:59Z")

</div>

This solves my issue. Thank you very much!

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [January 11, 2021, 2:20pm UTC](https://discourse.julialang.org/t/trouble-with-writing-a-mutable-struct-with-mvector-fields/53135/7 "2021-01-11T14:20:43Z")

</div>

> [@GrantHecht](#):
>
> Just removing the `<: Integer` type restriction still resulted in an error but removing both type restrictions as [leandromartinez98](https://discourse.julialang.org/u/leandromartinez98) suggested solved my issues.

Strange, in Julia 1.5.3 the below works for me:

```julia
julia> mutable struct Particle{M,T <: AbstractFloat}
       
           x::MVector{M,T} # Current Position
           v::MVector{M,T} # Current Velocity
           p::MVector{M,T} # Best Position
       
           fx::T # Current Objective Function Value
           fp::T # Best Objective Function Value
       
           function Particle(x::MVector{M,T}, v::MVector{M,T}) where {M, T <: AbstractFloat}
               xl = length(x)
               vl = length(v)
               if xl != vl
                   throw(ArgumentError("Particle's position and velocity must be the same length."))
               else
                   new{M,T}(x, v, NaN*similar(x), NaN*x[1], NaN*x[1])
               end
           end
       end

julia> a = MVector{3}(rand(3));

julia> b = MVector{3}(rand(3));

julia> Particle(a, b)
Particle{3,Float64}([0.32231386156690256, 0.41352687412221245, 0.924715838687213], [0.8347980122662781, 0.6946471924954924, 0.5798756616696423], [NaN, NaN, NaN], NaN, NaN)

```

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [January 11, 2021, 2:29pm UTC](https://discourse.julialang.org/t/trouble-with-writing-a-mutable-struct-with-mvector-fields/53135/8 "2021-01-11T14:29:24Z")

</div>

Here it works as well as Henrique indicates.

Nevertheless, I think the general advice here would be to not put that `<:AbstractFloat` restriction. Even if somewhat artificial, your particle structure could be used to store particles that have only integer positions, for example. The restriction does not add anything in terms of performance, because the instances of `Particle` will be of the number types you define on construction anyway.

I think you can be even more permissive, with something like:

```julia
julia> mutable struct P{T,M}
         x :: T
         y :: T
         p :: T
         fx :: M
         fp :: M
       end

julia> P(x) = P(x,x,x,zero(eltype(x)),zero(eltype(x)))
P

julia> x = rand(MVector{3,Float64})
3-element MArray{Tuple{3},Float64,1,3} with indices SOneTo(3):
 0.6445027572690152
 0.8155124942309746
 0.2684031014000019

julia> P(x)
P{MArray{Tuple{3},Float64,1,3},Float64}([0.6445027572690152, 0.8155124942309746, 0.2684031014000019], [0.6445027572690152, 0.8155124942309746, 0.2684031014000019], [0.6445027572690152, 0.8155124942309746, 0.2684031014000019], 0.0, 0.0)

```

The instance of “particle” has now a type signature which is even more specific than before, and that can help the compiler further, probably (maybe that does not make any difference, but certainly it won’t be worse).

---

<div class="post-metadata">

### Author: ![GrantHecht](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/granthecht/32/20898_2.png) [@GrantHecht](https://discourse.julialang.org/u/GrantHecht)
#### Post date: [January 11, 2021, 2:39pm UTC](https://discourse.julialang.org/t/trouble-with-writing-a-mutable-struct-with-mvector-fields/53135/9 "2021-01-11T14:39:23Z")

</div>

My apologies, I must have had a typo when implementing your suggestion Henrique. Nevertheless, thank you both for the great advice!
