How do I transform a vector into a Matrix

The code below creates three identical matrices, m1, m2, and m3 in three
different ways. m3 was created programatically. The function foo could
be anything the user would like it to be, subject to converting an Int into a
Float64.

m1 = [1.0 2.0]

typeof(m1) # Matrix{Float64} (alias for Array{Float64, 2})

m2 = Array{Float64}(undef, (1, 2))

m2[1,1] = 1.0

m2[1,2] = 2.0

typeof(m2) # Matrix{Float64} (alias for Array{Float64, 2})

m1 == m2 # true
typeof(m1) == typeof(m2) # true

m3 = Array{Float64}(undef, (1, 2))

function foo(i::Int)::Float64
    return Float64(i)
end    

for i in 1:2
    m3[1, i] = foo(i)
end

typeof(m3) # Matrix{Float64} (alias for Array{Float64, 2})

m1 == m3 # true
typeof(m1) == typeof(m3) # true

One alternative way to create a matrix like m1 would be to apply
a function to the vector v defined below. Of course it is easy to write
such a function. But it could already exist and be fast. Does such a
function exist in Base or in some package?

v1 = [1.0, 2.0]    

typeof(v1) # Vector{Float64} (alias for Array{Float64, 1})

typeof(v1) == typeof(m1) # false

# m4 = somefunction(v1)
# m4 == m1 true
# typeof(m4) == typeof(m1) true

Does this answer your question?

julia> m1 = [1.0 2.0]
1Ɨ2 Matrix{Float64}:
 1.0  2.0

julia> vec(m1)
2-element Vector{Float64}:
 1.0
 2.0

julia> reshape(m1, 2)
2-element Vector{Float64}:
 1.0
 2.0

Re-reading the title it seems you want to go the other way.

julia> v1 = [1.0, 2.0]
2-element Vector{Float64}:
 1.0
 2.0

julia> reshape(v1, (1,2))
1Ɨ2 Matrix{Float64}:
 1.0  2.0

julia> reshape(v1, (2,1))
2Ɨ1 Matrix{Float64}:
 1.0
 2.0

Also, you can broadcast foo with adding a ..

julia> v2 = [1,2,3]
3-element Vector{Int64}:
 1
 2
 3

julia> foo.(v2)
3-element Vector{Float64}:
 1.0
 2.0
 3.0

julia> M2 = [1 2 3]
1Ɨ3 Matrix{Int64}:
 1  2  3

julia> foo.(M2)
1Ɨ3 Matrix{Float64}:
 1.0  2.0  3.0

Thanks. reshape solved my problem.

For lovers of succinctness:

julia> v = [1, 2, 3]
3-element Vector{Int64}:
 1
 2
 3

julia> v[:,:]
3Ɨ1 Matrix{Int64}:
 1
 2
 3

Iā€™m fairly certain that your succinct version allocates a new matrix entirely, which the reshape version does not. May be relevant for someone doing that in a tight loop!

1 Like

Very true! If you want to avoid copying, you can do:

julia> m = @view v[:,:]
3Ɨ1 view(::Matrix{Int64}, :, :) with eltype Int64:
 1
 2
 3

julia> m[2,1] *= 100
200

julia> v
3-element Vector{Int64}:
   1
 200
   3