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"?