I don't understand this bit: "Numpy's notation has the advantage to make 
the most expensive operations harder to write, it also easily reminds us 
that arrays in numpy are row-major." How does this make the more expensive 
operation harder to write?

To me (but I didn't design Julia so what do I know) have a[i] refer to a 
specific element makes sense because it makes it easy to write a loop that 
does something to each element without having to worry about the dimensions 
of the array. 

On Friday, May 9, 2014 12:53:44 PM UTC+3, [email protected] wrote:
>
> Hi, my mind might be completely fried by intensive use of numpy arrays, 
> but I find slicing in Julia quite odd and I'd like to understand why. I'm 
> not saying Julia *should* behave like numpy but I find numpy's behaviour 
> really convenient. Let me explain...
>
> Let say I created a random 2D array in numpy and Julia which is:
> a = 0.618734  0.858034  0.261089
>     0.988064  0.323639  0.379946
>     0.571054  0.998853  0.453861
>     0.965824  0.629747  0.210426
>
> In numpy, a[0] would give:
> 0.618734  0.858034  0.261089
> and in Julia, a[1] would give:
> 0.618734
>
> In numpy, a[:] would give the whole matrix, in Julia, the flatten matrix.
>
> From what I've understood, these differences come down to the fact that 
> numpy arrays are considered as containers. The fact that default operators 
> act element-wise emphases that fact while Julia's arrays are not considered 
> only as containers but as algebraic objects. They are well defined in 1D 
> (vector) and 2D (matrix) but not that much for higher dimensional stuff 
> (tensors were evoked, with a generalisation of the dot product discussed 
> here <https://groups.google.com/forum/#!topic/julia-dev/gnizzJAU5RY>).
>
> In short the differences go down to: a[0] in numpy maps to a[1, :] in 
> Julia and a[1] in Julia maps to a[0, 0] in numpy in 2D. 
>
> Numpy's notation has the advantage to make the most expensive operations 
> harder to write, it also easily reminds us that arrays in numpy are 
> row-major.
>
> Julia's notation has the advantage of not doing stuff behind your back 
> (possibly saving a few CPU cycles), but at the expense of increased 
> verbosity. This is even more obvious when a 3D container should be 
> considered as a series of matrices: AFAIK, there is no way to cleanly 
> iterate over them. I'll have to rely on explicite indexing.
>
> Python:
> ref = rand(3,4) # matrix of 3 rows by 4 columns
> a = rand(5,4,3) # 5 matrices of 4 rows by 3 columns
> for i in a:
>     print(i.dot(ref))
> or, still in Python:
> ref = rand(3,4)
> a = rand(5,4,3)
> print(a.dot(ref))
> which is way faster than the first one.
>
>
> In Julia in comparison, this is not allowed and one has to rely on 
> explicit indexing:
> ref = rand(3,4) # matrix of 3 rows by 4 columns
> a = rand(4,3,5) # matrix of 4 rows by 3 columns, 5 times
> #a * ref        # Not working (yet)
> for i = 1:size(a)[3]
>     println(a[:, :, i] * ref)
> end
>
> The Python version is less verbose, but more importantly, you don't have 
> to think of row-major or column-major: if you need to get a transpose 
> somewhere, that means slower code. Whereas in Julia, println(a[:, :, i] * 
> ref) could be transformed to println(a[i, :, :] * ref) whithout realising 
> this could lead to inefficiencies. Of course, this can be written in Python 
> too, but that would also mean slower code.
>
> I'm not saying Julia should change and I understand that once a 
> generalised * operator lands, verbosity and innefficient constructs won't 
> be a problem anymore. But considering all of that, numpy's behavior still 
> looks more convenient (and this example runs twice faster on Python than on 
> Julia which indicates that the performance penalty of returning a matrix 
> the numpy's way is negligible).
>
> Why does Julia make the choice to return only one number when the ambigous 
> a[1] is executed?
>

Reply via email to