Bill, can you file a bug report for this?

https://github.com/JuliaLang/julia/issues?milestone=7&state=open

On Tue, 2014-07-01 at 09:59, mauro...@runbox.com wrote:
> Yes, this seems odd.  I think it's a bug.  First, this also works:
>
> function scale!{T<:Number}(A::Tridiagonal{T}, x::T)
>            Base.scale!(A.dl, x) 
>            Base.scale!(A.d,  x)
>            Base.scale!(A.du, x)
>            return
> end
>
> and is probably what you want as T needs to be a number for this to make
> sense.  Still:
>
> I tried reproducing this with another function, which then gives the
> expected ambiguity warning:
>
> julia> f{T,N}(X::AbstractArray{T,N},s::Number) = 1
> f (generic function with 1 method)
>
> julia> f{T}(X::Tridiagonal{T},s::T) = 1
> Warning: New definition 
>     f(Tridiagonal{T},T) at none:1
> is ambiguous with: 
>     f(AbstractArray{T,N},Number) at none:1.
> To fix, define 
>     f(Tridiagonal{_<:Number},_<:Number)
> before the new definition.
> f (generic function with 2 methods)
>
> julia> f{T<:Number}(X::Tridiagonal{T},s::T) = 1
> f (generic function with 3 methods)
>
> I think you're right, the scale! definition as you tried should give an
> ambiguity warning but it doesn't.  A bug.
>
> Then trying changing the order of above definitions does not give an
> ambiguity warning either.  I would have thought that ambiguities should
> be commutative?
>
> julia> f{T}(X::Tridiagonal{T},s::T) = 1
> f (generic function with 1 method)
>
> julia> A=Tridiagonal(rand(3),rand(4),rand(3));
>
> julia> f(A, 1.)
> 1
>
> julia> f{T,N}(X::AbstractArray{T,N},s::Number) = 2
> f (generic function with 2 methods)
>
> julia> f(A, 1.)
> 1
>
> julia> f(rand(3,3), 1.)
> 2
>
> julia> f{T<:Number}(X::Tridiagonal{T},s::T) = 3
> f (generic function with 3 methods)
>
> julia> f(A, 1.)
> 3
>
>
> On Tue, 2014-07-01 at 06:46, naelcml...@gmail.com wrote:
>> I wanted a scale! method that works for tridiagonal matrices and did the 
>> following.
>>
>> import Base.scale!
>>
>> function scale!{T}(A::Tridiagonal{T}, x::T)
>>     Base.scale!(A.dl, x) 
>>     Base.scale!(A.d,  x)
>>     Base.scale!(A.du, x)
>>     return
>> end
>>
>> Doing 
>>
>> methods(scale!)
>>
>> gives the output
>>
>> # 15 methods for generic function "scale!":
>> scale!{T<:Union(Complex{Float64},Float32,Complex{Float32},Float64)}(X::Array{T<:Union(Complex{Float64},Float32,Complex{Float32},Float64),N},s::T<:Union(Complex{Float64},Float32,Complex{Float32},Float64))
>>  
>> at linalg/dense.jl:11
>> ...
>> scale!(X::AbstractArray{T,N},s::Number) at linalg/generic.jl:20
>> ...
>> (A::CholmodSparse{T<:Union(Complex{Float64},Float32,Complex{Float32},Float64),Ti<:Union(Int64,Int32)},b::Array{T<:Union(Complex{Float64},Float32,Complex{Float32},Float64),1})
>>  
>> at linalg/cholmod.jl:907
>> scale!{T}(A::Tridiagonal{T},x::T) at none:2
>>
>> however
>>
>> A=Tridiagonal(rand(3),rand(4),rand(3))
>> 4x4 Tridiagonal{Float64}:
>>  0.342959   0.878001  0.0        0.0     
>>  0.0359927  0.481333  0.950373   0.0     
>>  0.0        0.764103  0.0200941  0.84859 
>>  0.0        0.0       0.220059   0.131956
>>
>> scale!(A,2.0)
>> ERROR: indexing not defined for Tridiagonal{Float64}
>>  in generic_scale! at linalg/generic.jl:16
>>  in scale! at linalg/generic.jl:20
>>
>> We can verify that Julia is not dispatching to the tridiagonal scale! 
>> method:
>>
>> which(scale!, (Tridiagonal{Float64},Float64))
>> scale!(X::AbstractArray{T,N},s::Number) at linalg/generic.jl:20
>>
>> If I change the first line of the function definition to
>>
>> function scale!(A::Tridiagonal,x)
>>
>> then I get some ambiguity warnings:
>>
>> Warning: New definition 
>>     scale!(Tridiagonal{T},Any) at none:2
>> is ambiguous with: 
>>     scale!(AbstractArray{T,N},Number) at linalg/generic.jl:20.
>> To fix, define 
>>     scale!(Tridiagonal{T},Number)
>> before the new definition.
>> Warning: New definition 
>>     scale!(Tridiagonal{T},Any) at none:2
>> is ambiguous with: 
>>     scale!(AbstractArray{T,2},AbstractArray{T,1}) at linalg/generic.jl:306.
>> To fix, define 
>>     scale!(Tridiagonal{T},AbstractArray{T,1})
>> before the new definition.
>> scale! (generic function with 15 methods)
>>
>> Sure enough, defining 
>>
>> function scale!(A::Tridiagonal, x::Number)
>>     Base.scale!(A.dl, x)
>>     Base.scale!(A.d,  x)
>>     Base.scale!(A.du, x)
>>     return
>> end
>>
>> works fine. I am a bit mystified by this behaviour.  Why was there no 
>> warning for my first attempt?
>> Is there a problem in general with making a method "too specific"?


Reply via email to