Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Multiply column of a matrix with row of another matrix in Julia

Let

A = rand(3,3);B = rand(3,3)

I can multiply first column of A : A[:,1] with third row of matrix B : B[3,:]
by the command:

reshape(A[:,1],3,1)*reshape(B[3,:],1,3)

to make a 3×3 matrix.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The direct computation

A[:,1]*B[3,:]

is giving the error:

ERROR: MethodError: no method matching *(::Vector{Float64}, ::Vector{Float64})
Closest candidates are:
  *(::Any, ::Any, ::Any, ::Any...) at operators.jl:560
  *(::StridedMatrix{T}, ::StridedVector{S}) where {T<:Union{Float32, Float64, ComplexF32, ComplexF64}, S<:Real} at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\matmul.jl:44
  *(::StridedVecOrMat{T} where T, ::LinearAlgebra.Adjoint{var"#s832", var"#s831"} where {var"#s832", var"#s831"<:LinearAlgebra.LQPackedQ}) at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\lq.jl:254
  ...
Stacktrace:
 [1] top-level scope
   @ REPL[2]:1

Is there any other short/clear method to do this operation?

Answer : A[:, 1:1] * B[3:3, :] and A[:, 1] * B[3, :]' from @phipsgabler’s reply. Or view(A, :, 1)*view(B, 3, :)' without copying rows or columns.

>Solution :

A[:, 1] and B[3, :] are both Vectors — rank 1 — so it is not automatically clear what you want here. The more likely option would be the inner product:

julia> dot(A[:, 1], B[3, :])
0.8875027511646011

julia> A[:, 1]' * B[3, :]
0.8875027511646011

But it seems you want the outer product:

julia> reshape(A[:,1],3,1)*reshape(B[3,:],1,3)
3×3 Matrix{Float64}:
 0.689437  0.246968   0.190616
 0.400674  0.143528   0.110778
 0.197257  0.0706608  0.0545377

julia> A[:, 1:1] * B[3:3, :]
3×3 Matrix{Float64}:
 0.689437  0.246968   0.190616
 0.400674  0.143528   0.110778
 0.197257  0.0706608  0.0545377

julia> A[:, 1] * B[3, :]'
3×3 Matrix{Float64}:
 0.689437  0.246968   0.190616
 0.400674  0.143528   0.110778
 0.197257  0.0706608  0.0545377

To explain: by using a range, 1:1, instead of an index, the result will still be a matrix (just like your reshape approach):

julia> B[3:3, :]
1×3 Matrix{Float64}:
 0.938292  0.336112  0.259419

That way the * is well defined as the matrix product between a one-column matrix and a one-row matrix.

The same holds if you transpose one of the vectors:

julia> B[3, :]'
1×3 adjoint(::Vector{Float64}) with eltype Float64:
 0.938292  0.336112  0.259419

The product between a vector and a covector is also well-defined.

The last option is to use kron; this however vectorizes the result, and you have to reshape the output:

julia> reshape(kron(A[:, 1], B[3, :]), 3, 3)
3×3 Matrix{Float64}:
 0.689437  0.400674  0.197257
 0.246968  0.143528  0.0706608
 0.190616  0.110778  0.0545377
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading