Base.call() in Julia 0.6

Hi All,

I can’t find information about the usage of base.call in Julia 0.6, but it breaks some code I have and that works well in Julia 0.5…

The function I am trying to run is

immutable SavitzkyGolayFilter{M,N} end

@generated function Base.call{M,N,T}(::Type{SavitzkyGolayFilter{M,N}},
     data::AbstractVector{T})

     #Create Jacobian matrix
     J = zeros(2M+1, N+1)
     for i=1:2M+1, j=1:N+1
         J[i, j] = (i-M-1)^(j-1)
     end
     e₁ = zeros(N+1) 
     e₁[1] = 1.0
    
     #Compute filter coefficients
     C = J' \ e₁

     #Evaluate filter on data matrix

     To = typeof(C[1] * one(T)) #Calculate type of output
     expr = quote
         n = size(data, 1)
         smoothed = zeros($To, n)
         @inbounds for i in eachindex(smoothed)
             smoothed[i] += $(C[M+1])*data[i]
         end
         smoothed
     end

     for j=1:M
         insert!(expr.args[6].args[2].args[2].args, 1,
             :(if i - $j ≥ 1
                 smoothed[i] += $(C[M+1-j])*data[i-$j]
               end)
         )
         push!(expr.args[6].args[2].args[2].args,
             :(if i + $j ≤ n
                 smoothed[i] += $(C[M+1+j])*data[i+$j]
               end)
         )
     end

     return expr
end

And it returns a

LoadError: UndefVarError: call not defined

in Julia 0.6. I think I have missed something there ?

1 Like

https://github.com/JuliaLang/julia/pull/13412
Base.call was deprecated in v0.5, it has been removed in v0.6.
I guess you could do something like this:

@generated function (::SavitzkyGolayFilter{M,N})(data::AbstractVector{T}) where {M, N, T}

1 Like

Thanks, I did not know about that.

I tried the piece of code you suggested but got an error: UndefVarError: M not defined

I don’t understand how I should declare the generated function there… Any idea?

immutable SavitzkyGolayFilter{M,N} end
@generated function (::SavitzkyGolayFilter{M,N})(data::AbstractVector{T}) where {M, N, T}
            #Create Jacobian matrix
            J = zeros(2M+1, N+1)
            for i=1:2M+1, j=1:N+1
                J[i, j] = (i-M-1)^(j-1)
            end
            e₁ = zeros(N+1) 
            e₁[1] = 1.0
           
            #Compute filter coefficients
            C = J' \ e₁

            #Evaluate filter on data matrix

            To = typeof(C[1] * one(T)) #Calculate type of output
            expr = quote
                n = size(data, 1)
                smoothed = zeros($To, n)
                @inbounds for i in eachindex(smoothed)
                    smoothed[i] += $(C[M+1])*data[i]
                end
                smoothed
            end

            for j=1:M
                insert!(expr.args[6].args[2].args[2].args, 1,
                    :(if i - $j ≥ 1
                        smoothed[i] += $(C[M+1-j])*data[i-$j]
                      end)
                )
                push!(expr.args[6].args[2].args[2].args,
                    :(if i + $j ≤ n
                        smoothed[i] += $(C[M+1+j])*data[i+$j]
                      end)
                )
            end

            return expr
end

This snippet works fine in julia-v0.6. Here are some tests:

julia> sgf = SavitzkyGolayFilter{3,2}()
SavitzkyGolayFilter{3,2}()

julia> sgf(1:10)
10-element Array{Float64,1}:
 0.952381
 1.90476 
 3.0     
 4.0     
 5.0     
 6.0     
 7.0     
 9.04762 
 8.57143 
 6.38095 

is this what you were looking for?

Yes, indeed, it works in Julia V0.6, but not in v0.5.2… I got a first error:

syntax: space before “{” not allowed in “where {”

and if I correct it by removing the space I get the error

UndefVarError: M not defined

where is a new syntax introduced in v0.6. In v0.5.2, your original version should work.

Yes, it works in 0.5.2, but is there any chance to make it work for both 0.5.2 and 0.6?

the corresponding version of where in v0.5 is @generated function (::SavitzkyGolayFilter{M,N}){M,N,T}(data::AbstractVector{T}) which works fine in both v0.5 and v0.6 :slight_smile:

1 Like