Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
240 views
in Technique[技术] by (71.8m points)

Julia matrix multiplication type behavior

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"?

question from:https://stackoverflow.com/questions/65906216/julia-matrix-multiplication-type-behavior

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...