How to create a 2x1 Array?

This seams to be simple to me:

julia> [2 4]'
2×1 Array{Int64,2}:
 2
 4

Does it not work any longer on 0.7?

It works, but it creates:

julia> [1 2]'
2×1 Adjoint{Int64,Array{Int64,2}}:
 1
 2

so it is a lazy adjoint.

On 0.7 you can use either:

permutedims([1 2])

or as I have noted above (which is a bit shorter and faster):

 hvcat(1, 1, 2)
1 Like

Thats bad. But what is the difference between an Adjoint and an array in the first place?

Here you can see two differences:

julia> x = [1im, 2im]
2-element Array{Complex{Int64},1}:
 0 + 1im
 0 + 2im

julia> y = x'
1×2 Adjoint{Complex{Int64},Array{Complex{Int64},1}}:
 0-1im  0-2im

julia> x[1,1] = 100
100

julia> x
2-element Array{Complex{Int64},1}:
 100 + 0im
   0 + 2im

julia> y
1×2 Adjoint{Complex{Int64},Array{Complex{Int64},1}}:
 100+0im  0-2im

julia> y[1,1]=10
10

julia> y
1×2 Adjoint{Complex{Int64},Array{Complex{Int64},1}}:
 10+0im  0-2im

julia> x
2-element Array{Complex{Int64},1}:
 10 + 0im
  0 + 2im

First - if you use complex numbers there is a difference. Second - it is a view of the original array.

Also the benefit of hvcat is that it works on 0.7 and 0.6.2.

No one has mentioned macros, but it’s trivial to write one for 2D array construction. Example:

julia> macro matrix(array)
         rows = [Expr(:row, val) for val in array.args]
         Expr(:vcat, rows...)
       end
@matrix (macro with 1 method)

julia> @matrix [1,2,3]
3×1 Array{Int64,2}:
 1
 2
 3
1 Like

This issue is related to the topic:
https://github.com/JuliaLang/julia/issues/7128

It seems there is no easy way to do this because the syntax [a;b] is reserved for array concatenation.
I agree with @Liso , the solutions proposed here are incredibly complicated for such simple task.

1 Like

Nice macro. The only drawback is that you have to interpolate if you want to pass a variable like @matrix $x.

This problem is because it is recursive operation. And it has impact not only to complex number:

# 0.6.1
julia> ["a" "b"]'
ERROR: MethodError: no method matching transpose(::String)

#0.7.0
julia> ["a" "b"]'
2×1 Adjoint{Any,Array{String,2}}:
Error showing value of type Adjoint{Any,Array{String,2}}:
ERROR: MethodError: no method matching adjoint(::String)

You could try to do it for Array of Arrays…

Agreed - that is why the documentation for ' states

This operation is intended for linear algebra usage

I guess.

1 Like

Slightly shorter option that works on both 0.6 and 0.7.

julia> hcat([1, 2])
2×1 Array{Int64,2}:
 1
 2
5 Likes

Reviewing the many solutions in this thread, it is apparent that while there are many ways to create single-column matrices, there is no special syntax for this.

I wonder if this is really a problem. Many types in Base has no short syntax, they are just constructed with a constructor or a function for this purpose. I can imagine three possibilities:

  1. Single-column matrices are not used frequently, eg because vectors are columns vectors in linear algebra, so they are rarely needed. When needed (eg for testing), there are workarounds. If a package uses a lot of these for some reason, they can define a function for it.

  2. They are used frequently enough that a constructor syntax is warranted in base. We can either

    a. co-opt one of the existing syntaxes for this, but this is proving to be difficult,

    b. introduce a special function, eg colmx or something like that.

I am leaning towards 1, but perhaps I just have different use cases.

Tbh I’m still in favour of

[1, 2, 3] -> Vector
[1 2 3]   -> 1x3 Matrix
[1; 2; 3] -> 3x1 Matrix

This seems like the only consistent option for literal syntaxes to me, but I can’t say I really care all that much :slight_smile:

14 Likes

FWIW, I can’t remember ever creating an Nx1 Matrix in the past year or so and I’m almost thinking it could be better that it is hard to create them as they are so rarely useful.

If instead there actually is a need for some syntax, maybe the easiest would be to add a Matrix(v::Vector) method that would create an Nx1 matrix, just in the same way as Matrix(v::RowVector) would create a 1xN Matrix. On 0.6 and master it is a method error, so I guess it wouldn’t be a breaking change.

1 Like

See also https://github.com/JuliaLang/julia/pull/23790.

Part of the rationale for not having an easy way to create an N-by-1 matrix is that such matrices are usually better treated as vectors. However, the return values of expressions like maximum(A, 2) go against this philosophy. The returned array will always have a singleton dimension. It would seem natural to let the maximum function squeeze out this dimension. If this were the case, then the code from the original post would have worked as intended.

Of course it is sometimes useful to preserve the singleton dimension, but one could perhaps distinguish between maximum(A, (2,)) which would squeeze, and maximum(A, [2]) which keep the current behavior.

(Of course this would affect a lot of existing code, and it’s too late for new features for 1.0 anyways.)

1 Like

I found this thread while scratching my head over array creation syntax. Why does Julia 1.1.0 still have two ways to make a vector, one way to make a 1×d array and zero ways to make a d×1 array? Can this still be changed?

julia> [1 2]
1×2 Array{Int64,2}:
 1  2

julia> [1,2]
2-element Array{Int64,1}:
 1
 2

julia> [1;2]
2-element Array{Int64,1}:
 1
 2

This is not correct, please review the solutions above.

Ok, sorry for not being clear on what I meant. I do use single column matrices and what I meant was:

Emphasis mine.

How about a macro?

julia> using MacroTools

julia> macro col(expr)
         @capture expr [x__]
         Expr(:call, :hvcat, Expr(:tuple, [1 for _ in x]...), esc.(x)...)
       end
@col (macro with 1 method)

julia> @col [1,2]
2×1 Array{Int64,2}:
 1
 2

julia> @col [1, 2, 3]
3×1 Array{Int64,2}:
 1
 2
 3
2 Likes