Best practices for generating vectors with ones, zeros, rand, etc

A common method to generate and initialize vectors using ones, zeros, or random values, is, e.g., ones(N,1).

However, in Julia, such initializations result in a matrix type (!) rather than a vector:
julia> VERSION
v"1.4.1"
julia> ones(2,1)
2×1 Array{Float64,2}:
1.0
1.0
julia> ones(1,2)
1×2 Array{Float64,2}:
1.0 1.0

This is also true for other functions such as zeros and randn. Usually this must not cause any problems. However, functions such as Diagonal change their behaviour based on the input type. This causes newbie (perhaps also for experienced users) problems. Furthermore, each call to ones, etc. has to be wrapped in a vec: Diagonal(vec(ones(2,1))) which is against Julia’s aim of better code clarity.

What are the best practices for generating vectors of zeros, ones, etc., so that the result is of vector type?

Definitely, I would prefer the functions to return vectors when the requested dimension unambiguously says so.

ones(2), rand(2) etc all do what you want and return a vector. The way to think about it is that the number of arguments you pass to them is the number of dimensions you want the output to have.

5 Likes

But that’s actually what it does. If you want to make a 2x1 matrix, how would you otherwise write it?

I’m guessing you learnt this from Matlab (I’m a Matlab user too), but it’s the same there; ones(2,1) returns a 2x1 matrix, just like Julia and numpy. The difference is just that in Matlab you cannot make a proper vector, only matrices.

Thank you. I think this is a consistent interface.

Nevertheless, what does a 3x1 array with dimension Array{Float62,2} mean?

When applied to the function Diagonal the dimension Array{Float62,2} or Array{Float62,1} seems to indicate the behaviour the function needs to adopt.

Personally to me, 3x1 arrays of type Array{Float62,2} and Array{Float62,1} are the same (the distinction is due to programming rather than mathematical expressivity) and I would be uncomfortable using the 2 vs 1 info to change the behaviour of the functions. This is because the inputs to Diagonal can come from anywhere (i.e. out of our control) and need to by typecast (with a vec, etc) each time.

Is it better to take this question up on LinearAlgebra GitHub issues list rather than discuss here? Perhaps this is a bit of a deviation from the original title of the question, but I think still relevant in scope.

Yes, indeed. The confusion is because I’m used to MATLAB where ones(2) is a 2x2 matrix. Please also see my comments to the earlier reply.

It’s better to discuss it here. It will definitely not be changed, since it has been extremely thoroughly discussed, and is without doubt the right design.

I’m going to say “trust me on this”. The confusion between vectors and matrices is one of the worst things about Matlab. The behavior of Julia and numpy is just vastly better.

2 Likes

MATLAB dosn’t have true (flat) vectors, even a scalar is a 1x1 matrix. So, both 3x1 and 1x3 are called vectors in MATLAB, and when they are input to diag, you get a matrix with the main diagonal as the entered vector elements. In Julia, n, 1xn, and nx1 are three different things. So, Diagonal sees ones(n) as a vector, nx1 and 1xn as 2D arrays, hence you get different results.

Julia’s approach is by far more accurate and consistent. The developers of Julia take such fundamental design decisions only after serious research and discussions. After a few days of using Julia all the misconceptions of MATLAB will naturally go away. Watch this talk, e.g., from Julia conference, to see how much study is done before any important design decision is taken in Julia.

1 Like

For another example of how seriously we’ve taken this, you could read https://github.com/JuliaLang/julia/issues/4774. It was the 400+ comment issue where tlots of this was figured out.

1 Like

Ok, guys. I think I have good pointers to read up now. Perhaps, as one of you mentions, it’s only a matter of getting used to Julia. I’ll report back if I have anything interesting to add besides the information in the supplied links and video.

PS: It’s a knowledgeable and considerate community here. Thank you!

3 Likes

Don’t hesitate to ask if things are still unclear. This is the right forum for it.

1 Like

I suggest you watch this excellent talk by Jiahao Chen on the subject from JuliaCon a couple of years ago:

1 Like

On this point strongly I agree — I really wish the Diagonal constructor didn’t have this confusion.

It is important to remember that 1-dimensional arrays are indeed different from 2-d arrays that happen to only have one column, but in the context of linear algebra we do try to make 1-d arrays participate in the algebra of matrices as consistently as possible.

2 Likes