JuliaStats / NMF.jl

A Julia package for non-negative matrix factorization
Other
90 stars 34 forks source link

Breaking change between 0.5.1 and 0.5.2 #62

Closed mileslucas closed 3 years ago

mileslucas commented 3 years ago

My test suite broke between these two releases. I've confirmed reverting to 0.5.1 passes tests, but on 0.5.2 they do not.

Tests: https://github.com/JuliaHCI/ADI.jl/blob/master/test/nmf.jl Stack trace:

Decomposition: Error During Test at /Users/miles/dev/julia/ADI/test/nmf.jl:9
  Got exception outside of a @test
  MethodError: no method matching scaleneg!(::SubArray{Float32, 1, Matrix{Float32}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}, ::SubArray{Float64, 1, Matrix{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}, ::Float64, ::Float32)
  Closest candidates are:
    scaleneg!(::Any, ::Any, ::T, ::T) where T<:Number at /Users/miles/.julia/packages/NMF/rycrA/src/initialization.jl:126
  Stacktrace:
    [1] _nndsvd!(X::Matrix{Float32}, W::Matrix{Float32}, Ht::Matrix{Float32}, inith::Bool, variant::Int64)
      @ NMF ~/.julia/packages/NMF/rycrA/src/initialization.jl:59
    [2] nndsvd(X::Matrix{Float32}, k::Int64; zeroh::Bool, variant::Symbol)
      @ NMF ~/.julia/packages/NMF/rycrA/src/initialization.jl:91
    [3] nndsvd(X::Matrix{Float32}, k::Int64)
      @ NMF ~/.julia/packages/NMF/rycrA/src/initialization.jl:76
    [4] fit(alg::NMF, data::Matrix{Float32}; ref::Matrix{Float32}, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
      @ ADI ~/dev/julia/ADI/src/nmf.jl:57
    [5] fit
      @ ~/dev/julia/ADI/src/nmf.jl:47 [inlined]
    [6] #fit#1
      @ ~/dev/julia/ADI/src/common.jl:54 [inlined]
    [7] fit(alg::NMF, cube::Array{Float32, 3})
      @ ADI ~/dev/julia/ADI/src/common.jl:48
    [8] macro expansion
      @ ~/dev/julia/ADI/test/nmf.jl:12 [inlined]
    [9] macro expansion
      @ ~/software/julia/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
   [10] top-level scope
      @ ~/dev/julia/ADI/test/nmf.jl:11
   [11] include(fname::String)
      @ Base.MainInclude ./client.jl:444
   [12] macro expansion
      @ ~/dev/julia/ADI/test/runtests.jl:18 [inlined]
   [13] macro expansion
      @ ~/software/julia/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
   [14] top-level scope
      @ ~/dev/julia/ADI/test/runtests.jl:18
   [15] include(fname::String)
      @ Base.MainInclude ./client.jl:444
   [16] top-level scope
      @ none:6
   [17] eval
      @ ./boot.jl:360 [inlined]
   [18] exec_options(opts::Base.JLOptions)
      @ Base ./client.jl:261
   [19] _start()
      @ Base ./client.jl:485
RDI Trivial: Error During Test at /Users/miles/dev/julia/ADI/test/nmf.jl:34
  Got exception outside of a @test
  MethodError: no method matching nmf_skeleton!(::NMF.CoordinateDescentUpd{Float32}, ::Matrix{Float64}, ::Matrix{Float64}, ::Matrix{Float64}, ::Int64, ::Bool, ::Float32)
  Closest candidates are:
    nmf_skeleton!(::NMF.NMFUpdater{T}, ::Any, ::Matrix{T}, ::Matrix{T}, ::Int64, ::Bool, ::Any) where T at /Users/miles/.julia/packages/NMF/rycrA/src/common.jl:40
  Stacktrace:
    [1] solve!(alg::NMF.CoordinateDescent{Float32}, X::Matrix{Float64}, W::Matrix{Float64}, H::Matrix{Float64})
      @ NMF ~/.julia/packages/NMF/rycrA/src/coorddesc.jl:49
    [2] fit(alg::NMF, data::Matrix{Float32}; ref::Matrix{Float64}, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
      @ ADI ~/dev/julia/ADI/src/nmf.jl:58
    [3] fit(alg::NMF, cube::Array{Float32, 3}; kwargs::Base.Iterators.Pairs{Symbol, Array{Float64, 3}, Tuple{Symbol}, NamedTuple{(:ref,), Tuple{Array{Float64, 3}}}})
      @ ADI ~/dev/julia/ADI/src/common.jl:52
    [4] reconstruct(alg::NMF, cube::Array{Float32, 3}; kwargs::Base.Iterators.Pairs{Symbol, Array{Float64, 3}, Tuple{Symbol}, NamedTuple{(:ref,), Tuple{Array{Float64, 3}}}})
      @ ADI ~/dev/julia/ADI/src/common.jl:109
    [5] subtract(alg::NMF, cube::Array{Float32, 3}; kwargs::Base.Iterators.Pairs{Symbol, Array{Float64, 3}, Tuple{Symbol}, NamedTuple{(:ref,), Tuple{Array{Float64, 3}}}})
      @ ADI ~/dev/julia/ADI/src/nmf.jl:32
    [6] macro expansion
      @ ~/dev/julia/ADI/test/nmf.jl:36 [inlined]
    [7] macro expansion
      @ ~/software/julia/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
    [8] top-level scope
      @ ~/dev/julia/ADI/test/nmf.jl:35
    [9] include(fname::String)
      @ Base.MainInclude ./client.jl:444
   [10] macro expansion
      @ ~/dev/julia/ADI/test/runtests.jl:18 [inlined]
   [11] macro expansion
      @ ~/software/julia/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
   [12] top-level scope
      @ ~/dev/julia/ADI/test/runtests.jl:18
   [13] include(fname::String)
      @ Base.MainInclude ./client.jl:444
   [14] top-level scope
      @ none:6
   [15] eval
      @ ./boot.jl:360 [inlined]
   [16] exec_options(opts::Base.JLOptions)
      @ Base ./client.jl:261
   [17] _start()
      @ Base ./client.jl:485

This can be recreated in a minimum working example by having a non-float64 data type

using NMF
X = randn(Float32, 50, 1000)
NMF.nndsvd(X, 5) # errors
NMF.nndsvd(Float64.(X), 5) # works as expected
ghost commented 3 years ago

Thank you for your bug report. I misunderstood rsvd() function. The function takes float32 data but returns float64 data. So MethodError arises in scaleneg!(). I'll fix the problem soon.