# Summing matrices of different dimensions in a type stable way?

**URL:** <https://discourse.julialang.org/t/summing-matrices-of-different-dimensions-in-a-type-stable-way/1952>\
**Category:** General Usage\
**Created:** [February 7, 2017, 10:28am UTC](https://discourse.julialang.org/t/summing-matrices-of-different-dimensions-in-a-type-stable-way/1952 "2017-02-07T10:28:51Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [February 7, 2017, 10:28am UTC](https://discourse.julialang.org/t/summing-matrices-of-different-dimensions-in-a-type-stable-way/1952/1 "2017-02-07T10:28:51Z")

</div>

I want to have a type (or maybe another container) that contains matrices of different dimensions and be able to do operations (like summing them), but I’m having trouble doing this in a type stable way. Something like:

```julia
    type Container
        mat#::?
    end

    function mysum(c::Container)
        s = 0.0
        for m in c.mat
            s += sum(m)
        end
        s
    end

    c = Container([rand(10,10),rand(10)])
    @code_warntype mysum(c)

```

Doesn’t work because `[rand(10,10),rand(10)]` is not homogeneous (can’t declare it as `Array{Array{Float64,N},1}` for a fixed N).

Using a recursive definition of `mysum` improves things a bit but the top function remains unstable:

```julia
    mysum2(c::Container) = mysum2((c.mat...))
    mysum2(args) = mysum2(0.0,args...)
    mysum2(out::Float64,mat::Array{Float64},rest...) = out + mysum2(sum(mat),rest...)
    mysum2(out::Float64,mat::Array{Float64}) = out + sum(mat)

    @code_warntype mysum2( (c.mat...) ) #type stable, but
    @code_warntype mysum2( c ) #type unstable

```

I could generate a collection of types of the sort:

```julia
    type Container2{N1,N2}
        m1::Array{Float64,N1} 
        m2::Array{Float64,N2}
    end

```

But that’s not very elegant.

Am I missing something obvious here ? Is there a pattern to solve this kind of issues ?

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [February 7, 2017, 10:56am UTC](https://discourse.julialang.org/t/summing-matrices-of-different-dimensions-in-a-type-stable-way/1952/2 "2017-02-07T10:56:10Z")

</div>

Have you tried using a tuple, possibly combined with the recursion?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 7, 2017, 12:44pm UTC](https://discourse.julialang.org/t/summing-matrices-of-different-dimensions-in-a-type-stable-way/1952/3 "2017-02-07T12:44:47Z")

</div>

> [@mauro3](#):
>
> Have you tried using a tuple, possibly combined with the recursion?

A tuple works fine; no need for recursion:

```julia
julia> m = (rand(3), rand(3,3), rand(3,3,3))
([0.175138,0.460267,0.13993],
[0.751967 0.93118 0.102488; 0.967268 0.6361 0.0838402; 0.674022 0.343599 0.899127],

[0.478299 0.752114 0.657615; 0.172727 0.6258 0.781415; 0.202425 0.200734 0.69294]

[0.39174 0.776263 0.504116; 0.309226 0.536818 0.383052; 0.0128251 0.867464 0.521238]

[0.755321 0.856696 0.95617; 0.762188 0.849155 0.57642; 0.611566 0.281467 0.462158])

julia> f(m) = sum(sum, m)
f (generic function with 1 method)

julia> @code_warntype f(m)
Variables:
  #self#::#f
  m::Tuple{Array{Float64,1},Array{Float64,2},Array{Float64,3}}

Body:
  begin 
      return $(Expr(:invoke, LambdaInfo for mapfoldl(::Base.#sum, ::Function, ::Tuple{Array{Float64,1},Array{Float64,2},Array{Float64,3}}), :(Base.mapfoldl), :(Main.sum), :(Base.+), :(m)))
  end::Float64

```

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [February 7, 2017, 1:02pm UTC](https://discourse.julialang.org/t/summing-matrices-of-different-dimensions-in-a-type-stable-way/1952/4 "2017-02-07T13:02:30Z")

</div>

Ok, so the trick is keep the tuple all the way up. I was still trying to put it in a container.

I have to say having to work with big tuples instead of types that show nicely is not very elegant either. Is there a better solution on the roadmap ?

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 7, 2017, 2:00pm UTC](https://discourse.julialang.org/t/summing-matrices-of-different-dimensions-in-a-type-stable-way/1952/5 "2017-02-07T14:00:08Z")

</div>

You can just define your own `show` method for your type to display however you would like.

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [February 7, 2017, 2:59pm UTC](https://discourse.julialang.org/t/summing-matrices-of-different-dimensions-in-a-type-stable-way/1952/6 "2017-02-07T14:59:53Z")

</div>

Yes but we are speaking about using tuples instead of custom types here. I mean you can overwrite `show` for some tuples of arrays, but that’s not exactly ideal.

When you try to write something a bit more involved than `sum` it also quickly gets complicated (admittedly I’m not used to work with tuples, maybe it gets easier with practice).

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [February 7, 2017, 7:47pm UTC](https://discourse.julialang.org/t/summing-matrices-of-different-dimensions-in-a-type-stable-way/1952/7 "2017-02-07T19:47:35Z")

</div>

You can wrap the tuple in a type like so:

```julia
immutable MyType{T<:Tuple}
    tup::T
end

```

(note that the type parameter is needed.) You can then define a custom show method on the `MyType` (and for instance also implement the array interface)

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [February 7, 2017, 8:31pm UTC](https://discourse.julialang.org/t/summing-matrices-of-different-dimensions-in-a-type-stable-way/1952/8 "2017-02-07T20:31:46Z")

</div>

Yeah, the `T<:Tuple` was what I was missing, I think that will solve most of my issues. Thanks.

---

<div class="post-metadata">

**Author:** ![fengyang.wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fengyang.wang/32/104_2.png) [@fengyang.wang](https://discourse.julialang.org/u/fengyang.wang)\
**Post date:** [February 8, 2017, 6:05am UTC](https://discourse.julialang.org/t/summing-matrices-of-different-dimensions-in-a-type-stable-way/1952/9 "2017-02-08T06:05:38Z")

</div>

If your real-world data is going to have dimensions larger than 10 by 10, I would ignore type stability for summing over the container and just use a `Vector{Array{Float64}}`, then assert the result type if I know it to prevent type instability from propagating. For large data, the cost of dynamic dispatch to vectorized container operations is probably negligible.
