A common use case for me, and lots of people I would think, is to have large systems of DEs such as

dx_i / dt = …
dy_i / dt = …

where i \in [1, n] and x_i, y_i represents the ith class of x, y respectively.

Usually I define the state in these ODEs as one big vector of length 2n, like

const n = 100 #some number of dimensions
system_state = zeros(2*n)
system_state[1:n] #these are the x_i
system_state[n+1:2*n] #these are the y_i

Then the ODE function is something like this, with all the operations broadcasted

function f(du,u,p,t)
x = @view u[1:n]
y = @view u[n+1:2*n]
du[1:n] .= -1 .* x
du[n+1:2*n] .= x .* y
end

This works, but I end up having lots of slices around my code, which can be difficult to read.
I was hoping there was a zero-cost way of writing a shorthand function like

x(state) = @view state[1:n]

which I can then use to modify the state exactly like the original slice. However this doesn’t seem to work, I get the error “invalid assignment location”.

I have a quick question related to the use of labelledarrays in this way.
My current toy example is

function f(du,u,p,t)
x = @view u[1:n]
y = @view u[n+1:2*n]
du[1:n] .= -1 .* x
du[n+1:2*n] .= -1 .* y
end
const n = 10
u_0 = @LArray fill(1.0,2*n) (x = (1:n),y = (n+1:2*n))
prob = ODEProblem(f,u_0,(0,10.0),[])
sol = solve(prob,Tsit5())

Is it possible to define a custom type of labelledarray, like say state_type = LArray{2*n}(x = (1:n),y = (n+1:2*n)), so I can easily specify function signatures that return labelled arrays with the format of u_0? I’ve tried a few different things and none of them worked.

Let me know if this should be asked as a new topic or not as well.