Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia matrix multiplication type behavior

Tags:

types

julia

I'd like to ask about some bizarre behavior I noticed in Julia. Consider the following snippet:

function wut()
   mat::Array{Number,2}=[1 2 3; 5 6 7]
   mat2::Array{Number,2}=[1 1; 2 3]
   return typeof(mat2*mat)
end
wut()

Enormously proud of itself, this outputs Array{Any,2}. What is going on here? Why isn't the output Array{Number,2}? If one replaces Number with Float64 the output is Array{Float64,2} as it should be, but why does julia think that the multiplication of two matrices made of abstract "numbers" should come out as a matrix made up of "anything under the sun"?

like image 996
cbartondock Avatar asked Mar 02 '23 18:03

cbartondock


1 Answers

Here's an alternative answer: this is a quirk and implementation detail that should ideally not exist. It's not a result of Julia's type design or dispatch, nor is it really a great design pattern. It's just the status quo.

Matrix multiplication is based upon an in-place API. That is, A*B becomes mul!(output_array, A, B). Thus, we need to pre-allocate the result before actually knowing what will happen. The computation of this output element type is done by a quirky and ill-specified function: promote_op. It's something that really should be removed but would require a huge and difficult refactor... and thus we have strange cases like this.

For more details, see the docstring of Base.promote_op (note that it's unexported and doesn't even appear in the online manual):

help?> Base.promote_op
  promote_op(f, argtypes...)

  Guess what an appropriate container eltype would be for storing results of
  f(::argtypes...). The guess is in part based on type inference, so can
  change any time.

  │ Warning
  │
  │  Due to its fragility, use of promote_op should be avoided. It is
  │  preferable to base the container eltype on the type of the actual
  │  elements. Only in the absence of any elements (for an empty result
  │  container), it may be unavoidable to call promote_op.

For more internal details on promote_op see issue #19669, comments in #25689, and their discussion.

like image 106
mbauman Avatar answered Mar 23 '23 00:03

mbauman