# Iterating over the columns of a matrix

**URL:** <https://discourse.julialang.org/t/iterating-over-the-columns-of-a-matrix/39385>\
**Category:** Performance\
**Tags:** question, iterative, arrays\
**Created:** [May 13, 2020, 9:56am UTC](https://discourse.julialang.org/t/iterating-over-the-columns-of-a-matrix/39385 "2020-05-13T09:56:08Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![BMO](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmo/32/14820_2.png) [@BMO](https://discourse.julialang.org/u/BMO)\
**Post date:** [May 13, 2020, 9:56am UTC](https://discourse.julialang.org/t/iterating-over-the-columns-of-a-matrix/39385/1 "2020-05-13T09:56:08Z")

</div>

I want to iterate a function whose argument is a vector. The vectors to iterate on are the columns of a matrix. I was “slicing” the matrix into columns following [Converting a matrix into an array of arrays](https://discourse.julialang.org/t/converting-a-matrix-into-an-array-of-arrays/17038/3) and then iterate over the new array whose entries are the vectors I want.

I think it is not optimal and that is my first question: If all I want is to iterate over the columns of a matrix, then shouldn’t I define an iterator (instead of copying the whole matrix)?  
So, I came up with the following code which does the trick, but I am not sure whether this is the right way to define such iterator (e.g. are the last two lines strictly necessary? defining the length gives me problems with the length function…)

```julia
struct AbstractMatrixColumn
    M::AbstractMatrix
end

function Base.iterate(M::AbstractMatrixColumn)
    state = 1
    return Base.iterate(M,state)
end

function Base.iterate(M::AbstractMatrixColumn, state)
    if state > size(M.M,2)
        next = nothing
    else
        next = M.M[:,state], state+1
    end
    return next
end

Base.length(M::AbstractMatrixColumn) = size(M.M,2)
Base.eltype(M::AbstractMatrixColumn) = typeof(M.M[:,1])

```

Coming back to [Converting a matricx into an array of arrays](https://discourse.julialang.org/t/converting-a-matrix-into-an-array-of-arrays/17038/3), now we can use this iterator to collect the columns of a matrix `M` with `collect(AbstractMatrixColumns(M))`, but it is much slower. Is it supposed to be or it is a problem with my implementation?

```julia
function slicematrix_column(M::AbstractMatrix{T}) where T
    return [M[:,i] for i in 1:size(M,2)]
end

n = 1000;
N = rand(n,n);
@btime collect(AbstractMatrixColumn($N));
@btime slicematrix_column($N);

> julia
  2.083 ms (6945 allocations: 7.87 MiB)
  1.329 ms (1003 allocations: 7.76 MiB)

```

---

<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:** [May 13, 2020, 10:04am UTC](https://discourse.julialang.org/t/iterating-over-the-columns-of-a-matrix/39385/2 "2020-05-13T10:04:22Z")

</div>

This is what `eachcol`, `eachrow` and `eachslice` are for:

```julia
julia> A = rand(0:9, 4,5)
4×5 Array{Int64,2}:
 9 2 8 7 6
 2 4 9 0 6
 4 4 4 5 3
 3 0 7 3 1

julia> for col in eachcol(A)
       println(col)
       end
[9, 2, 4, 3]
[2, 4, 4, 0]
[8, 9, 4, 7]
[7, 0, 5, 3]
[6, 6, 3, 1]

```

These iterators return views, in case that’s relevant, while your code makes copies.

---

<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:** [May 13, 2020, 10:13am UTC](https://discourse.julialang.org/t/iterating-over-the-columns-of-a-matrix/39385/3 "2020-05-13T10:13:19Z")

</div>

BTW, a performance issue in your code is that you have an abstract type signature in the field of `AbstractMatrixColumn`. If you want to experiment furter with this, you should make that field concrete or parametric.

---

<div class="post-metadata">

**Author:** ![BMO](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmo/32/14820_2.png) [@BMO](https://discourse.julialang.org/u/BMO)\
**Post date:** [May 13, 2020, 10:49am UTC](https://discourse.julialang.org/t/iterating-over-the-columns-of-a-matrix/39385/4 "2020-05-13T10:49:12Z")

</div>

Thank you so much @DNF. Yes, I want to experiment further 😄
