# How to calculate sum of a matrix by row and store in pre-allocated diagnoal matrix

**URL:** https://discourse.julialang.org/t/how-to-calculate-sum-of-a-matrix-by-row-and-store-in-pre-allocated-diagnoal-matrix/64160
**Category:** Numerics
**Created:** [July 6, 2021, 4:42pm UTC](https://discourse.julialang.org/t/how-to-calculate-sum-of-a-matrix-by-row-and-store-in-pre-allocated-diagnoal-matrix/64160 "2021-07-06T16:42:25Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Fred\_He](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fred_he/32/14298_2.png) [@Fred\_He](https://discourse.julialang.org/u/Fred_He)
#### Post date: [July 6, 2021, 4:42pm UTC](https://discourse.julialang.org/t/how-to-calculate-sum-of-a-matrix-by-row-and-store-in-pre-allocated-diagnoal-matrix/64160/1 "2021-07-06T16:42:25Z")

</div>

basically what I want to do is calculate the sum of a matrix, say u, by column and store it in a pre-allocated diagonal matrix, say du, in a more efficient way than

```julia
vi = sum(u, dims=2)
for i = 1:length(vi)
    du[i, i] = vi[i]
end

```

the whole idea is that i need to do an operation:  
` usg* A1*u + Deg*A2*u`  
A1 and A2 do the first and second derivation. This is a typical operation in the simulation of the convection-diffusion phenomenon. If `usg` is a diagonal matrix or a constant, the equation can be calculated with inplace operation (with an intermediate vector `du` )  
`mul!( lmul!(usg, mul!( du, A1, u)), A2, u, Deg, true)`

In my case, Deg can be seen as constant. But usg is no constant and calculated from u by  
`usg = sum(u, dims=2)*const ./v1`.  
As v1 is a constant vector, first I can make a diagnoal matrix  
`rv1 = Diagnoal(1 ./v1)`  
so  
`usg = sum(u, dims=2)*const ./v1 = rv1*sum(u, dims=2)*const`  
and can be calculated using inplace operator  
`mul!(usg, rv1, lmul!(const, du)` (take `du = sum(u, dims=2)` is the intermediate vector)  
But now usg is a vector because `sum(u, dims=2)` is an vector.

So is there a way to make `sum(u, dims=2)` to store in a diagonal matrix? or is there a simpler way to realize the whole operation (` usg* A1*u + Deg*A2*u` ) ?

thanks for reading and giving advice.

---

<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: [July 6, 2021, 4:59pm UTC](https://discourse.julialang.org/t/how-to-calculate-sum-of-a-matrix-by-row-and-store-in-pre-allocated-diagnoal-matrix/64160/2 "2021-07-06T16:59:06Z")

</div>

> [@Fred\_He](#):
>
> So is there a way to make `sum(u, dims=2)` to store in a diagonal matrix?

If `A` is a matrix and `D` is a pre-allocated `Diagonal` matrix of an appropriate size, `Base.mapreducedim!(identity, Base.add_sum, transpose(D.diag .= 0), A)` should work.

Or you can just write a nested loop, of course, which is probably clearer than using undocumented internals.

---

<div class="post-metadata">

### Author: ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)
#### Post date: [July 6, 2021, 5:22pm UTC](https://discourse.julialang.org/t/how-to-calculate-sum-of-a-matrix-by-row-and-store-in-pre-allocated-diagnoal-matrix/64160/3 "2021-07-06T17:22:23Z")

</div>

You can just use `sum!`:

```julia
julia> D = Diagonal(rand(3));

julia> u = reshape(1:9, 3, 3);

julia> sum!(D.diag, u);

julia> D
3×3 Diagonal{Float64, Vector{Float64}}:
 12.0 ⋅ ⋅ 
   ⋅ 15.0 ⋅ 
   ⋅ ⋅ 18.0

julia> vi = sum(u, dims=2)
3×1 Matrix{Int64}:
 12
 15
 18

julia> Base.mapreducedim!(identity, Base.add_sum, transpose(D.diag .= 0), u)
1×3 transpose(::Vector{Float64}) with eltype Float64:
 6.0 15.0 24.0

```

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [July 6, 2021, 5:53pm UTC](https://discourse.julialang.org/t/how-to-calculate-sum-of-a-matrix-by-row-and-store-in-pre-allocated-diagnoal-matrix/64160/4 "2021-07-06T17:53:04Z")

</div>

> [@mcabbott](#):
>
> `julia> sum!(D.diag, u);`

Here’s a solution that doesn’t access the internal fields of `D`, in case you care about this:

```julia
sum!(view(D, diagind(D)), u)

```

It is significantly slower than `sum!(D.diag, u)`, though. I cannot seem to find an efficient view of a `Diagonal` matrix’es diagonal (aside from accessing the `diag` field.)

---

<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: [July 6, 2021, 6:10pm UTC](https://discourse.julialang.org/t/how-to-calculate-sum-of-a-matrix-by-row-and-store-in-pre-allocated-diagnoal-matrix/64160/5 "2021-07-06T18:10:59Z")

</div>

> [@mcabbott](#):
>
> You can just use `sum!` :

Doh, I forgot we had that! I wonder why we don’t have a (documented) `mapreduce!` function?

---

<div class="post-metadata">

### Author: ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)
#### Post date: [July 6, 2021, 6:31pm UTC](https://discourse.julialang.org/t/how-to-calculate-sum-of-a-matrix-by-row-and-store-in-pre-allocated-diagnoal-matrix/64160/6 "2021-07-06T18:31:56Z")

</div>

In BandedMatrices.jl there’s `view(A, band(0))` but it may not be that efficient

---

<div class="post-metadata">

### Author: ![Fred\_He](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fred_he/32/14298_2.png) [@Fred\_He](https://discourse.julialang.org/u/Fred_He)
#### Post date: [July 7, 2021, 7:50am UTC](https://discourse.julialang.org/t/how-to-calculate-sum-of-a-matrix-by-row-and-store-in-pre-allocated-diagnoal-matrix/64160/7 "2021-07-07T07:50:27Z")

</div>

Thanks a lot for the discussion. Really helpful!
