It returns a column instead of a 1x2 array. It doesn’t even show the dimension. Like:
C = [3 8]
1×2 Array{Int64,2}:
3 8
The 2 element array above (N[1,:] should be 1x2 array, and in row format, not column/vector. Same result in jupyter and the REPL. To post multiply by this result, I have to transpose first to get it back to a row, where it should be a row to begin with.
Any help appreciated, I’m not sure if there’s a reason that it works this way - is it meant to or is something wrong?
I,e. instead of giving a scalar index, pass a collection of indices for slicing, like when you do N[1:2,:] - although that collection has only one index.
Longer explanation of why is it like that in a recent discussion:
Among the different replies given in the linked discussion, I think that this one by Oscar Smith is the clearest, so perhaps it will make sense after reading it:
Yeah, I agree with DNF that N[1:1, :] is probably more idiomatic.
One way to understand it is that a 1D Vector is not the same as an Nx1Matrix (i.e. a column), even though they are often interchangeable.
The indexing rules in Julia are agnostic to the dimensionality of the array, i.e. they work the same with 1D, 2D, 3D, etc.
See this post with some more examples of indexing and dimensionality. The general rule is that when you index dimension D, the dimesionality of the result for that dimension is the same as the dimension of the index, so if you index with a zero-dimensional index (a scalar) that dimension is dropped. If you index with a 1-dimensional index (a vector, range, etc.) the dimension is retained. If you index with a 2D index you actually add a dimension.
I think (though I haven’t verified exhaustively) that you can write the general rule as
This does make more sense to me, but it still seems like that should be taken care of internally without having to specify a range. If : only returns 1 value then it should be scalar, otherwise, it should have the dimensions of the piece that you’re looking for. I come from Python, so using : is handled as I’d expect.
C = A[2,:]
2-element Array{Int64,1}:
3
8
C = A[2:2,:]
1×2 Array{Int64,2}:
3 8
There’s often a consistency/convenience trade-off. Opinions definitely differ but I think consistency is usually a better target because what’s convenient for one application is often inconvenient for another.
In this case it’s nice to know what the dimensionality of the output will be when you use :, without having to worry about how many rows or columns the input has. for example, if I have A=rand(3,4) and B=rand(1,4), it would be surprising (to me) if A[:,1] had a different shape than B[:,1].
The reason Julia doesn’t do this is a consequence of a very important idea in Julia which is type stability.
Put simply, since Julia has multiple dispatch, good performance depends on the ability of the compiler to know what types your functions will output based on the types of their input. This allows the compiler to skip dynamic dispatch which is relatively slow.
This means that 2:2 should be of the same type as 2:3 since both construct a range with 2 Int arguments. Then A[2:2,:] should have the same type as A[2:3,:] since in both cases getindex is provided arguments of the same type.
The more I think about this, the more I think that this is a flaw in Julia. If A[:,1] returns an nx1 column (which it does), then A[1:n] should return a 1xn row (which it doesn’t, it returns something that looks like a column, but doesn’t have any dimension attached). It’s a question of consistency.
Maybe I posted this in the wrong place. In this case, the program author now has to write array indices in an odd way - I suspect that this is more an issue of how the author of the Julia module implemented things. It should be easier than this. Typing issues should be sorted out in the background, not by the user.
As DNF has already indicated, your assumption is wrong: A[:,1] does not return a column matrix, but a vector (an array of values with only one dimension).
Maybe you are accustomed to another language that does something different, but that doesn’t mean that such behavior is “a flaw”. And actually it’s the same in languages as popular as Python (with Numpy):…
>>> import numpy as np
>>> A = np.array([[1,2], [3,4]])
>>> A[0,:]
array([1, 2])
>>> A[:,0]
array([1, 3])