Using CartesianIndices with view()

I’ve got this function for computing the next state of a CA:

 function convGOL_dot(A::AbstractMatrix, kern::AbstractMatrix)
 	b = CartesianIndex(1,1)
 	out = zeros(eltype(A), size(A))
 	@inbounds for i in CartesianIndices(A)[2:end-1, 2:end-1]
 		count = dot(A[i-b:i+b], kern)
 		out[i] = liveordie(count, A[i])
 	end
 	out
 end

Given the right 3x3 kernel this function does what I want it to - it functions correctly. However, those 2D array slices there (A[i-b:i+b]) result in a lot of unnecessary allocations. I’d like to replace that line where the dot product is being calculated with a view into A. Something along the lines of:

 function convGOL_dot(A::AbstractMatrix, kern::AbstractMatrix)
 	b = CartesianIndex(1,1)
 	out = zeros(eltype(A), size(A))
 	@inbounds for i in CartesianIndices(A)[2:end-1, 2:end-1]
 		count = dot(view(A, i-b, i+b), kern)
 		out[i] = liveordie(count, A[i])
 	end
 	out
 end

… though that’s not doing the correct thing (the view isn’t producing a 3x3 2d array which causes the dot function to fail with a dimension mismatch). Is there something I need to do differently to use CartesianIndex’es there? How would I go about this?

I get BoundsError: attempt to access 5×5 Matrix{Float64} at index [1, 1, 3, 3] with the following test case:

A = zeros(5,5);
b = CartesianIndex(1,1);
i = first(CartesianIndices(A)[2:end-1, 2:end-1]);
view(A, i-b, i+b)

I think you want view(A, i-b:i+b).

1 Like

Thanks, that works. It seems I was over-complicating it.