# Combining `eachindex` and `axes`?

One of the things I like about `eachindex` is that you can give it several arrays and it throws a `DimensionMismatch` if they have different sizes.

I wonder if it would make sense to enable the same with `axes(A, d)`, possibly choosing a different `d` for each `A`. With such a syntax, I would write a matrix-vector product like this:

``````function matvec!(y::Vector{T}, A::Matrix, x::Vector) where {T}
for i in axes((y, A), (1, 1))
y[i] = zero(T)
for j in axes((A, x), (2, 1))
y[i] += A[i, j] * x[j]
end
end
end
``````

and the indexing would be safe by default, which means I could sprinkle `@inbounds` and `@simd`. Currently, this is of course feasible but a little more clumsy:

``````function matvec!(y::Vector{T}, A::Matrix, x::Vector) where {T}
@assert axes(y, 1) == axes(A, 1)
@assert axes(x, 1) == axes(A, 2)
for i in axes(y, 1)
y[i] = zero(T)
for j in axes(x, 1)
y[i] += A[i, j] * x[j]
end
end
end
``````
3 Likes

StaticArrayInteface.jl has an `indices` function which does exactly this:

``````julia> using StaticArrayInterface: indices

julia> function matvec!(y::Vector{T}, A::Matrix, x::Vector) where {T}
for i in indices((y, A), (1, 1))
y[i] = zero(T)
for j in indices((A, x), (2, 1))
y[i] += A[i, j] * x[j]
end
end
end;

julia> let x = rand(10), A = rand(10, 10), y = similar(x)
matvec!(y, A, x)
y ≈ A * x
end
true
``````
2 Likes

Good to know that it exists! I guess I was wondering if it deserves a place in `Base` to encourage correctness when iterating on several arrays