朱莉娅的@。宏和二元运算符

时间:2018-02-01 22:35:04

标签: julia

据我所知,以下内容应该是等同的:

julia> rand(2).^2
2-element Array{Float64,1}:
 0.164246
 0.47107 

julia> @. rand(2)^2
ERROR: DimensionMismatch("Cannot multiply two vectors")
Stacktrace:
 [1] power_by_squaring(::Array{Float64,1}, ::Int64) at ./intfuncs.jl:169
 [2] broadcast(::##65#66) at ./sysimg.jl:86

同样适用于此:

julia> 1./rand(2)
2-element Array{Float64,1}:
 1.93886
 3.01834

julia> @. 1/rand(2)
ERROR: MethodError: no method matching /(::Int64, ::Array{Float64,1})
Closest candidates are:
  /(::PyCall.PyObject, ::Any) at /home/simon/.julia/v0.6/PyCall/src/pyoperators.jl:11
  /(::Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}, ::Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}) at int.jl:38
  /(::Union{Int16, Int32, Int64, Int8, UInt16, UInt32, UInt64, UInt8}, ::BigInt) at gmp.jl:381
  ...
Stacktrace:
 [1] broadcast(::##69#70) at ./sysimg.jl:86

我到底做错了什么?

1 个答案:

答案 0 :(得分:6)

  

帮助&GT?; @。

     

@。 EXPR

     

将expr中的每个函数调用或运算符转换为“dot call”   (例如,将f(x)转换为f.(x)),并将expr中的每个作业转换为   “点分配”(例如,将+=转换为.+=)。

     

如果您想避免为所选函数调用添加点   expr,使用$ 拼接这些函数调用。

     

例如,@. sqrt(abs($sort(x)))相当于sqrt.(abs.(sort(x)))(没有点为   排序)。

问题在于,这种方式也是广播rand@.宏适用于所有函数调用,包括二元运算符调用(即。1 + 1被解析为+(1, 1) })

  1. 使用@macroexpand宏来查看宏调用的结果表达式。

  2. 使用$(f(x))插入您不想广播的函数调用(@.)。

  3. julia> @macroexpand @. rand(2)^2
    :(^.(rand.(2), 2))    # same as: rand.(2).^2
    
    julia> eval(ans)
    ERROR: DimensionMismatch("Cannot multiply two vectors")
    
    julia> @macroexpand @. $(rand(2))^2
    :(^.(rand(2), 2))  # same as: rand(2).^2
    
    julia> eval(ans)
    2-element Array{Float64,1}:
     0.26266
     0.326033
    
    julia> @macroexpand @. 1 / rand(2)
    :(/.(1, rand.(2)))    # same as: 1 ./ rand.(2)
    
    julia> eval(ans)
    ERROR: MethodError: no method matching /(::Int64, ::Array{Float64,1})
    
    julia> @macroexpand @. 1 / $(rand(2))
    :(/.(1, rand(2)))    # same as: 1 ./ rand(2)
    
    julia> eval(ans)
    2-element Array{Float64,1}:
     37.1023
      1.08004