I do not seem to understand the use of @evalpoly
(doc)
julia> @evalpoly(3.0, 1)
ERROR: BoundsError: attempt to access (1,)
at index [0]
julia> f(p) = @evalpoly(3.0, p)
ERROR: BoundsError: attempt to access (:p,)
at index [0]
julia> f(p) = @evalpoly(1, p...)
ERROR: BoundsError: attempt to access (:(p...),)
at index [0]
From what I understand, the first error comes from https://github.com/JuliaLang/julia/blob/e976e63cc791411b1e7d88b7ca705e87e10d8574/base/math.jl#L110.
As for the second and third, is there a way to delay the evaluation of the macro until p
is passed to the function f
? Or is this not the way the macro is intended to be used?
Thanks,
michele
The whole point of this macro is to inline the evaluation of a polynomial whose degree (and usually its coefficients) is known at compile time. This allows things like polynomial approximations of special-function implementations to be extremely efficient. Hence, the arguments must be an explicit list of coefficients.
(The case of a single coefficient, i.e. a degree-0 polynomial, is so pointless that we never implemented it. i.e. you might as well just write 1
instead of @evalpoly 3.0 1
. We might as well implement it for completeness, I suppose.)
So, for example, if you knew that p
was an array of length 4, you could do:
julia> f(p) = @evalpoly(1, p[1], p[2], p[3], p[4])
f (generic function with 1 method)
julia> f([2,3,4,5])
14
In practice, @evalpoly
is mainly used in cases where the coefficients are compile-time constants as well, mainly in the implementation of special functions like erfinv
and polygamma
.
If you have an array p
whose length is not known, there is no point in using a macro to evaluate the polynomial. It will need an explicit loop that is evaluated at runtime, rather than at compile-time as in @evalpoly
.
At one point, I suggested that we have an evalpoly
function for runtime evaluation of polynomials (RFC: add evalpoly function, mirroring @evalpoly macro by stevengj · Pull Request #7186 · JuliaLang/julia · GitHub), but there wasn’t much interest. In most such cases you probably want to use the Polynomials.jl package.
3 Likes
Thank you for the reply and the example.
I remember that at a certain point, you (most likely) implemented a horner
method (or a macro) and I could not find it anymore. The @evalpoly
is what came up when I searched the latest documentation for horner.
I completely agree with you that the evaluation of a 0th order polynomial is useless for the specialized cases of special functions.
I believe Stefan Karpinski addressed this specific macro at about 50m in the Julia - To Lisp or not to Lisp talk on YouTube.
Hope it helps.
3 Likes
Interesting presentation, @evalpoly
macro aside. Thank you.
1 Like
My pleasure - but we should probably be thanking Stefan!
-mrg