# What is wrong with [1.] * [1.]?

The following example shows that `*` performs matrix-matrix multiplication and matrix-vector multiplication but throws an error if the size of the operands is 1-by-1. I can get away with this error if I use elementwise multiplication `.*` in case of 1-by-1 operands. But I do not want check the sizes of the operands each time. Any ideas about getting rid of this error without size check each time?

``````
julia> a  = [1. 2.; 3. 4.]
2×2 Array{Float64,2}:
1.0  2.0
3.0  4.0

julia> b  = [5., 6.]
2-element Array{Float64,1}:
5.0
6.0

julia> c  = [7. 8. 9.; 10. 11. 12.]
2×3 Array{Float64,2}:
7.0   8.0   9.0
10.0  11.0  12.0

julia> d = [1.]
1-element Array{Float64,1}:
1.0

julia> a * b  # Matrix vector multiplication
2-element Array{Float64,1}:
17.0
39.0

julia> a * c  # Matrix matrix multiplication
2×3 Array{Float64,2}:
27.0  30.0  33.0
61.0  68.0  75.0

julia> d  * d
ERROR: MethodError: no method matching *(::Array{Float64,1}, ::Array{Float64,1})
Closest candidates are:
*(::Any, ::Any, ::Any, ::Any...) at operators.jl:502
*(::Adjoint{#s549,#s548} where #s548<:Union{DenseArray{T<:Union{Complex{Float32}, Complex{Float64}, Float32, Float64},2}, ReinterpretArray{T<:Union{Complex{Float32}, Complex{Float64}, Float32, Float64},2,S,A} where S where A<:Union{SubArray{T,N,A,I,true} where I<:Tuple{AbstractUnitRange,Vararg{Any,N}where N} where A<:DenseArray where N where T, DenseArray}, ReshapedArray{T<:Union{Complex{Float32}, Complex{Float64}, Float32, Float64},2,A,MI} where MI<:Tuple{Vararg{SignedMultiplicativeInverse{Int64},N} where N} where A<:Union{ReinterpretArray{T,N,S,A} where S where A<:Union{SubArray{T,N,A,I,true} where I<:Tuple{AbstractUnitRange,Vararg{Any,N} where N} where A<:DenseArray where N where T, DenseArray} where N where T, SubArray{T,N,A,I,true} where I<:Tuple{AbstractUnitRange,Vararg{Any,N} where N} where A<:DenseArray where N where T, DenseArray}, SubArray{T<:Union{Complex{Float32}, Complex{Float64}, Float32, Float64},2,A,I,L} where L where I<:Tuple{Vararg{Union{Int64, AbstractRange{Int64}, AbstractCartesianIndex},N} where N} where A<:Union{ReinterpretArray{T,N,S,A} where S where A<:Union{SubArray{T,N,A,I,true} where I<:Tuple{AbstractUnitRange,Vararg{Any,N} where N} where A<:DenseArray where N where T, DenseArray} where N where T, ReshapedArray{T,N,A,MI} where MI<:Tuple{Vararg{SignedMultiplicativeInverse{Int64},N} where N} where A<:Union{ReinterpretArray{T,N,S,A} where S where A<:Union{SubArray{T,N,A,I,true} where I<:Tuple{AbstractUnitRange,Vararg{Any,N} where N} where A<:DenseArray where N where T, DenseArray} where N where T, SubArray{T,N,A,I,true} where I<:Tuple{AbstractUnitRange,Vararg{Any,N} where N} where A<:DenseArray where N where T, DenseArray} where N where T, DenseArray}} where #s549, ::Union{DenseArray{S,1}, ReinterpretArray{S,1,S,A} where S where A<:Union{SubArray{T,N,A,I,true} whereI<:Tuple{AbstractUnitRange,Vararg{Any,N} where N} where A<:DenseArray where N where T, DenseArray}, ReshapedArray{S,1,A,MI} where MI<:Tuple{Vararg{SignedMultiplicativeInverse{Int64},N} where N} where A<:Union{ReinterpretArray{T,N,S,A} where S where A<:Union{SubArray{T,N,A,I,true} where I<:Tuple{AbstractUnitRange,Vararg{Any,N} where N} where A<:DenseArray where N where T, DenseArray} where N where T, SubArray{T,N,A,I,true} where I<:Tuple{AbstractUnitRange,Vararg{Any,N} where N} where A<:DenseArray where N where T, DenseArray}, SubArray{S,1,A,I,L} where L where I<:Tuple{Vararg{Union{Int64, AbstractRange{Int64}, AbstractCartesianIndex},N} where N} where A<:Union{ReinterpretArray{T,N,S,A} where S where A<:Union{SubArray{T,N,A,I,true} where I<:Tuple{AbstractUnitRange,Vararg{Any,N} where N} where A<:DenseArray where N where T, DenseArray} where N where T, ReshapedArray{T,N,A,MI} where MI<:Tuple{Vararg{SignedMultiplicativeInverse{Int64},N} where N} where A<:Union{ReinterpretArray{T,N,S,A} where S where A<:Union{SubArray{T,N,A,I,true} where I<:Tuple{AbstractUnitRange,Vararg{Any,N} where N} where A<:DenseArray where N where T, DenseArray} where N where T, SubArray{T,N,A,I,true} where I<:Tuple{AbstractUnitRange,Vararg{Any,N} where N} where A<:DenseArray where N where T, DenseArray} where N where T, DenseArray}}) where {T<:Union{Complex{Float32}, Complex{Float64}, Float32, Float64}, S} at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/LinearAlgebra/src/matmul.jl:97
*(::Adjoint{#s549,#s548} where #s548<:LinearAlgebra.AbstractTriangular where #s549, ::AbstractArray{T,1} where T) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/LinearAlgebra/src/triangular.jl:1805
...
Stacktrace:
 top-level scope at none:0

``````

I think the problem is `d` is of type `Vector` and these is no vector-vector multiplication (not mentioning vector cross product but cross product is for vectors having length greater or equal to three) mathematically. Just element-wise multiplication of two vectors is possible. Anyway,as the `*` does not have vector-vector multiplication method, are there any functions that can be used for 1-by-1 matrix multiplication.

Maybe helpful: there are 1-element Vectors `v = [2.5]` and one element matrices

``````julia> A = fill(2.5,1,1)
1×1 Array{Float64,2}:
2.5

julia> A*A
1×1 Array{Float64,2}:
6.25
``````

and these are not the same. . `fill` is a bit clumsy way to create them. Using these, the 1x1 case does not need to be special cased.

1 Like

Thank you for the reply @mschauer. But the problem is that I need to process the arrays instead of creating them.

I thought multiple dispatch can be used here as follows.

``````
julia> mul(a::Matrix, b::VecOrMat) = a * b
mul (generic function with 1 method)

julia> mul(a::Vector, b::Vector) = length(a) == length(b) == 1 ? [a * b] :
error("Vector lengths are greater than 1.")
mul (generic function with 2 methods)

julia> a = [1. 2.; 3. 4.];

julia> b = [5.; 6.];

julia> c = [7. 8. 9.; 10. 11. 12.];

julia> d = [1.];

julia> mul(a, b)
2-element Array{Float64,1}:
17.0
39.0

julia> mul(a, c)
2×3 Array{Float64,2}:
27.0  30.0  33.0
61.0  68.0  75.0

julia> mul(d, d)
1-element Array{Float64,1}:
1.0

julia> mul(b, b)
ERROR: Vector lengths are greater than 1.
Stacktrace:
 mul(::Array{Float64,1}, ::Array{Float64,1}) at ./none:1
 top-level scope at none:0

julia>
``````

1x1 matrix multiplication works fine. Why do you want to multiply length-1 vectors?

If you want to multiply vectors with each other, you should use element-wise multiplication: `.*`. Why special-case length-1 vectors, in that case?

1 Like

I am trying to solve a differential equation in the form of `xdot = A * x + B * u(t)`. where `A`, `B` are the system parameters, `x` is the state vector and `t` is the time and `u` is the input function. Then the right hand side function corresponding to the differential equation problem is

``````f(dx, x, u, t) = (dx .= A * x + B * u(t))
``````

Thus if `dx = [0.], x=[1.], A=[-1.], B=[1.], u = t -> t` and I try to call `f(dx, x, u, t)` I get the error explained in the previous posts.

I do not want to use element-wise multiplication in order not to loosen the restriction for the multiplication of vectors having lengths greater than 1 since I am having the problem with just length one vector.

It looks to me like `A` and `B` should be 1x1 matrices. And it also seems like `u` should return a vector.

The problem now seems to be that the types in the equation do not make sense.

Or maybe just use scalars?

It works if you transpose one of the 1-element arrays:

``````julia> [1.]'*[1.]
1.0
``````

(Note the single quote following the first array, which transposes that array)

1 Like

Yes, `A` should be defined as `A = fill(1, 1, 1)` as you and @mschauer offered. This prevents `A` to be vector and makes it a matrix. Then since `A` is a matrix and `x=[1.]` is a vector, no problem occurs in `A * x`.

1 Like