Can I create a reference to a section of a matrix without copying its elements?

In my code I have some 3D matrices M[m,i,j] where I iterate much less frequent over the first index (m: timestep) than over the other two (i,j: spatial discretization). I would like to have an alias for M[m, :, :] so I can operate on a 2D matrix within the timestep loop to make the code more compact and easy to read, especially when passing the 2D matrix to multiple other functions.

In the first block, when I change X, M changes too. I would like to achieve the same behavior in the second block where M is not changed (and I assume its values are copied to X because I observed increased runtime).

M = zeros(3,3,3)
X = M
X[1,1,1] += 1
@show M

M = zeros(3,3,3)
X = M[1,:,:]
X[1,1] += 1
@show M

Is there a way to create such a reference or is my need for it an indicator that my design is fundamentally flawed?
Thank you very much in advance!

Hello and welcome to the community :wave:

You want to create a view into the array. You can do this with the function view or the macros @view or @views.

X = @views M[1,:,:]
X[1,1] += 1
@show M
2 Likes

That’s very elegant and makes so much sense. I wasn’t familiar with views before. Thank you!

1 Like

I’ll add a little bit of additional commentary:

As a column-major object, the “fastest” indices in an Array are the first ones. This matches MATLAB but is opposite to NumPy. This is to say that you might get faster performance storing M as M[i,j,m] rather than your current M[m,i,j], since it appears that your “tight loop” actions are over i,j rather than m.

Further (and unlike MATLAB, NumPy, and some other tools), Julia handles arrays-of-arrays quite nicely and with decent performance. If you’re commonly slicing M[:,i,j] and also M[m,:,:] then you might truly be better off with your current 3D array approach. On the other hand, if most of your slicing is only one of those, then arrays-of-arrays are probably cleaner to work with. From your description, you would probably organize things to index as M[m][i,j] if you went this direction.

3 Likes