# Loops with arrays of arbitrary dimensions

Assume that I have a 2D array `A` and I want to do something like this

``````N1, N2 = 4, 3
A = ones((N1, N2))

x = zeros(N1)
for i2=1:N2
for i1=1:N1
x[i1] = 2 * A[i1, i2]
end
end

x = zeros(N2)
for i1=1:N1
for i2=1:N2
x[i2] = 2 * A[i1, i2]
end
end

``````

Then, in case of 3D array `A` I will need to add one extra loop:

``````N1, N2, N3 = 4, 3, 2
A = ones((N1, N2, N3))

x = zeros(N1)
for i3=1:N3
for i2=1:N2
for i1=1:N1
x[i1] = 2 * A[i1, i2, i3]
end
end
end

# etc.
``````

Now let’s assume I have an n-dimensional array `A`, and I want to specify some axis `ax` along which I want to multiply `A` by 2 and put the result to `x` (similarly to the above examples). The corresponding pseudo code can look like

``````ax = m

A = zeros((N1, N2, ..., Nn))

x = zeros(Nm)

for in=1:Nn
for i(n-1)=1:N(n-1)
...
for i(m+1)=1:N(m+1)
for i(m-1)=1:N(m-1)
...
for i2=1:N2
for i1=1:N1
for im=1:Nm
x[im] = 2 * A[i1, i2, ..., i(m-1), im, i(m+1), ..., i(n-1), in]
end
end
end
...
end
end
...
end
end
``````

However, I want a generic code which will not depend on the number of `A` dimensions, i.e. some function `foo(x, A, ax)` which will do what I want independently of the size of `A`. How I should write such kind of code with loops for arbitrary dimension of `A`?
So far I found only this old blog post which proposes to use macros. Did something changed since then? Can the corresponding loops be written with `ndims` and `axes` functions without macro?

You are looking for `CartisianIndices`

``````julia> x2 = rand(2, 2);

julia> x3 = rand(2, 2, 2);

julia> for c in CartesianIndices(x2)
@show x2[c]
end
x2[c] = 0.4108577974629497
x2[c] = 0.4591618516787277
x2[c] = 0.22742754395597542
x2[c] = 0.9850643176704423

julia> for c in CartesianIndices(x3)
@show x3[c]
end
x3[c] = 0.2229783161443213
x3[c] = 0.4984591608388653
x3[c] = 0.4418623143086191
x3[c] = 0.6718510628390104
x3[c] = 0.21610541455088628
x3[c] = 0.574532213871789
x3[c] = 0.02381508624762918
x3[c] = 0.9172113813322624
``````

There is also `@nloops` 

Can you please give me an example how I can write, let say, the following loop in terms of CartesianIndices:

``````N1, N2 = 4, 3
A = ones((N1, N2))

x = zeros(N1)
for i2=1:N2
for i1=1:N1
x[i1] = 2 * A[i1, i2]
end
end
``````

`CartesianIndices(A)` and `CartesianIndices(x)` have different dimensions.

I think this might be an XY problem. In the example above, you are overwriting `x` many times. Do you mean to have a `+=` intead of an `=`?

Assuming this is what you want to do, you would write it like this:

``````for I in CartesianIndices(A)
i1 = I
x[i1] = 2 * A[I]
end
``````
4 Likes

Its just a fake example which came to my mind. It can be either of them.

Then @jipolanco 's solution above is what you want.

Thank you. Seems like what I need.
Just a small question. Why do I need to take Tuple of I? It seems to work with just I.

Oops, you’re totally right about that! I wasn’t sure that it worked.

Thank you all guys for the help.