Base.call() in Julia 0.6


#1

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 ?


#2


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}


#3

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?


#4
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?


#5

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


#6

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


#7

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


#8

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: