2
votes

Multiplying two multi-dimensional arrays, say, a 1-dimensional with a 3-dimensional array:

[1 2] * reshape(1:8,2,2,2)

gives me the error message:

LoadError: MethodError: `*` has no method matching *(::Array{Int64,2}, ::Array{Int64,3})
Closest candidates are:
  *(::Any, ::Any, !Matched::Any, !Matched::Any...)
  *{TA,TB}(::Union{DenseArray{TA,1},DenseArray{TA,2},SubArray{TA,1,A<:DenseArray{T,N},I<:Tuple{Vararg{Union{Colon,Int64,Range{Int64}}}},LD},SubArray{TA,2,A<:DenseArray{T,N},I<:Tuple{Vararg{Union{Colon,Int64,Range{Int64}}}},LD}}, !Matched::Base.LinAlg.AbstractTriangular{TB,S<:AbstractArray{T,2}})
  *{TA,TQ,N}(::Union{DenseArray{TA,N},SubArray{TA,N,A<:DenseArray{T,N},I<:Tuple{Vararg{Union{Colon,Int64,Range{Int64}}}},LD}}, !Matched::Union{Base.LinAlg.QRCompactWYQ{TQ,M<:AbstractArray{T,2}},Base.LinAlg.QRPackedQ{TQ,S<:AbstractArray{T,2}}})
  ...
while loading In[167], in expression starting on line 1

 in Ac_mul_B at operators.jl:157

using the math definition of multi-dimensional matrix algebra for a (1 by 2) * (2 by 2 by 2) multiplication of matrices/arrays.

A somewhat more general example can be A*B = C meaning sum_k A_{i,j,k} B_{k,l,m} = C_{i,j,l,m}, where A is a 3-index matrix, or tensor if you like, B is a 3-index one, and the resulting C is a four index matrix/tensor, but, in general, there can be any number of dimensions and a dimension can have any size (within reason). See more info on the definition of a matrix product or tensor contraction.

What is the right syntax of this multiplication in Julia?

2
use .* instead of *Gnimuc
What do you mean with "math definition of multi-dimensional matrix algebra". Tensor product? The tensor product between matrices is obtained by kron. Or the elementwise product .*?mschauer
@mschauer To make it general enough to understand, by A*B = C I mean sum_k A_{i,j,k} B_{k,l,m} = C_{i,j,l,m}, where A is a 3-index matrix, or tensor if you like, B is a 3-index one, and the resulting C is a four index matrix/tensor. See: en.wikipedia.org/wiki/… for a definition of a matrix product. My above definition is just a generalization for n-dimensional matrices for n>2. If you are familiar with Matlab, this operation is done by * there.Ferenc
@Vincent Zoonekynd Exactly!Ferenc

2 Answers

2
votes

You can use reshape to convert the multi-dimensional arrays into matrices, multiply them, and convert the result back to a multi-dimensional array.

A = [1 2]
B = reshape(1:8,2,2,2)
reshape( reshape(A,2,1)' * reshape(B,2,4), 2, 2 )

(In this example, since A is already a matrix, there is actually no need to reshape it.)

1
votes

Matrices multiplication: use *

Matrices element-wise multiplication: use .*

If you want to multiply two matrices A*B, the size of both must much: e.g. size of A (a1,a2), size of B (b1, b2); in order to make the multiplication feasible a2 must be the same as b1

In your case:

julia> A=[1 2]
1x2 Array{Int64,2}:
 1  2

julia> size(A) #remember that size(A') is (2,1)
(1,2)

julia> B=reshape(1:8,2,2,2)
2x2x2 Array{Int64,3}:
[:, :, 1] =
 1  3
 2  4

[:, :, 2] =
 5  7
 6  8

julia> size(B)
(2,2,2)

julia> size(B[:,:,1])
(2,2)   

julia> A*B[:,:,1]
1x2 Array{Int64,2}:
 5  11

julia> A*B[:,:,2]
1x2 Array{Int64,2}:
 17  23

Edit: Multiplication in "one shot" (separated for clarity):

julia> A*B[:,:,1]
1x2 Array{Int64,2}:
 5  11

julia> A*B[:,:,2]
1x2 Array{Int64,2}:
 17  23

julia> C=A*B[:,:]
1x4 Array{Int64,2}:
 5  11  17  23

julia> size(C)
(1,4)

julia> D1 = reshape(C, 2,2)
2x2 Array{Int64,2}:
  5  17
 11  23

julia> D2 = reshape(C, 2,2)'
2x2 Array{Int64,2}:
  5  11
 17  23

Truly in one shot:

julia> D = reshape(A*B[:,:], 2,2)
2x2 Array{Int64,2}:
  5  17
 11  23