Vcat row vectors -> matrix?

Say, you want a 2 x 3 matrix from two 3-element row vectors. The simplest way I can think of currently is

a = [1, 2, 3]
b = [10,20,30]
m2x3 = transpose(hcat(a,b))

This isn’t bad at all, but I thought the right way would be vcatting the two row vectors, except that I don’t know how to create a row vector. It seems that normal vectors are (treated as?) column vectors and so vcat(a,b) simply creates a 6-element vector. . . .

Edit: In my real problem, I read a and b from external sources. So, we have to use a and b.

If you directly want to write the matrix, you can do

m2x3 = [1  2  3; 
        10 20 30]

Here you can see different ways to concatenate Multi-dimensional Arrays · The Julia Language.

Otherwise, for real valued vectors you could also write [a'; b'] where the ' is for the adjoint Linear Algebra · The Julia Language.

2 Likes

Vectors are by default treated as columns in Julia. If you want them to be row vectors, you can do [1 2 3] (without the commata). When you vcat([1,2,3], [4,5,6]), that essentially means

[
    [
        1;
        2;
        3
    ];
    [
        4;
        5;
        6
    ]
]
1 Like

Sorry guys that I wasn’t clear in my initial post! In my real situation, I read a and b from external files and therefore I need a solution using vectors a and b:

# . . . read vectors a and b from external sources
m2x3 = transpose(hcat(a,b))

@SteffenPL Yes, a and b are real (Float64) vectors, so your solution

m2x3 = [a' ; b']

should work. For real vectors and matrices, the adjoint (Hermitian conjugate) is the same as transpose. Thank you for the idea. As an extension,

m2x3 = [transpose(a); transpose(b)]

should work, whether a and b are real or not.

1 Like

Wait. I’ve tried that on the Julia interpreter and found that its type is 1×3 Matrix{Int64}.

That means that the most straightforward solution to my problem would be

a = Array{Int}(undef, 1, 3)
b = Array{Int}(undef, 1, 3)
# . . . read a and b from files . . .
m2x3 = vcat(a,b)

Thank you for the idea.

So, I wonder why is this asymmetry in Julia:

julia> [1 2 3]
1×3 Matrix{Int64}:
 1  2  3

julia> [1; 2; 3]
3-element Vector{Int64}: # <- Shouldn't this be 3x1 Matrix{Int64} ?
 1
 2
 3

julia> [1, 2, 3]
3-element Vector{Int64}: # fine.
 1
 2
 3

A vector and a column matrix are conceptually identical in Julia. Unless you specifically request a matrix, no reason to hold on to lagging singleton dimensions.

A vector and a column matrix are conceptually identical in Julia.

Yes, thanks, but my question is, what was the reason for that decision? I thought that a Vector is only treated as a column vector in certain contexts. If that were the case, we could have this situation:

[1, 2, 3] # <- a Vector, neither column or row.
[1  2  3] # <- 1x3 Matrix, which *is* a row vector.
[1; 2; 3] # <- 3x1 Matrix, which *is* a column vector.

I thought this would have been cleaner. In reality, [1; 2; 3] isn’t a 3x1 Matrix; it’s a Vector. This is confusing, because

[ [1 2], [3 4], [5 6] ]  # a Vector of 1x2 Matrices
[ [1 2]; [3 4]; [5 6] ]  # a 3x2 Matrix

So, the Vector notation [a, b, c, . . .] is always a Vector whereas the matrix notation [a; b; c; . . . ] tries to fuse the elements to create a single matrix.

I think we could turn it around: why would the opposite decision be made? The only thing that would change if we didn’t assume vectors to be columns is that fewer functions would work on vectors. As to why semicolon concatenates while comma lists, that just utilizes the different syntaxes to do slightly different things.

There’s a bit of history and a very long thought process in a GitHub issue (which I don’t have the number for offhand) PR that has gone into this design. You can read a summary at Julia 1.7 Highlights.

A 3x1 Matrix literal can be written as

julia> [1; 2; 3;;]
3×1 Matrix{Int64}:
 1
 2
 3

No, [1, 2, 3] is more different from [1;2;3] and [1 2 3] than you think. The first is vector literal construction, while the latter two are vertical and horizontal concatenation. They have very different behavior, except for scalars, where they seem similar.

If you take two vectors, v and w, then it is pretty obvious that vcat(v, w) must be a vector, not an Nx1 matrix. The same applies for scalars. It is also clearly different from [v, w], which is a vector of vectors.

For this reason I really dislike it when people write [1;2;3] for vector construction. They are, imho, semantically different.

1 Like