Julia @evalpoly宏与varargs

时间:2015-01-21 21:21:26

标签: julia

我正试图使用​​Julia的@evalpoly宏。当我手动提供系数时,它可以工作,但我无法解决如何通过数组提供这些系数

julia> VERSION
v"0.3.5"

julia> @evalpoly 0.5 1 2 3 4
3.25

julia> c = [1, 2, 3, 4]
4-element Array{Int64,1}: 
 1
 2
 3
 4

julia> @evalpoly 0.5 c
ERROR: BoundsError()

julia> @evalpoly 0.5 c...
ERROR: BoundsError()

julia> @evalpoly(0.5, c...)
ERROR: BoundsError()

有人能指出我正确的方向吗?

看到这个问题的好答案后添加

在我使用其中一些答案之前,我还没有看到一个微妙之处。 z的{​​{1}}参数可以是变量,但系数应该是文字

@evalpoly

查看最后一个命令扩展的输出,可以看出确实是这样的情况,z被分配给扩展中的变量,但系数被字面插入到代码中。

julia> z = 0.5
0.5

julia> @evalpoly z 1 2 3 4
3.25

julia> @evalpoly z c[1] c[2] c[3] c[4]
ERROR: c not defined

3 个答案:

答案 0 :(得分:8)

我不相信你想要做的事情是可能的,因为@evalpoly是一个宏 - 这意味着它在编译时生成代码。它产生的是Horner方法的非常有效的实现(在实数情况下),但是这样做需要知道多项式的程度。在编译时不知道c的长度,因此它不会(并且不能)工作,而当您直接提供系数时,它具有所需的一切。

错误信息不是很好,所以如果可以,你可以在Julia Github页面上提出问题吗?

更新:在回答问题的更新时,是的,第一个参数可以是变量。你可以这样想:

function dostuff()
  z = 0.0
  # Do some stuff to z
  # Time to evaluate a polynomial!
  y = @evalpoly z 1 2 3 4
  return y
end

正在成为

function dostuff()
  z = 0.0
  # Do some stuff to z
  # Time to evaluate a polynomial!
  y = z + 2z^2 + 3z^3 + 4z^4
  return y
end

除了,不是这样,因为它使用Horners统治,但无论如何。问题是,它不能在编译时生成该表达式而不知道系数的数量。但它并不需要知道z究竟是什么。

答案 1 :(得分:7)

Julia中的宏应用于他们的参数。要使其工作,您需要确保在评估c之前展开@evalpoly。这有效:

function f()
    c=[1,2,3,4]
    @eval @evalpoly 0.5 $(c...)
end

此处,@eval评估其参数,并展开$(c...)。之后,@evalpoly会看到五个参数。

如上所述,这可能效率不高,因为每次调用函数@eval时都会调用f。您需要在函数定义之外将调用移至@eval

c=[1,2,3,4]
@eval begin
    function f()
        @evalpoly 0.5 $(c...)
    end
end

在定义@eval时调用f。显然,此时必须知道c。实际调用f时,c不再使用;它仅在定义f时使用。

答案 2 :(得分:4)

Erik和Iain在解释为什么@evalpoly不起作用以及如何强迫它发挥作用方面做得很好。但是,如果您只想评估多项式,最简单的解决方案可能只是使用Polynomials.jl

julia> using Polynomials
       c = [1,2,3,4]
       polyval(Poly(c), 0.5)
3.25
相关问题