ComponentArrays.jl icon indicating copy to clipboard operation
ComponentArrays.jl copied to clipboard

vcat ambiguity with SparseArrays method

Open visr opened this issue 1 year ago • 2 comments

I was looking at a question in Discourse and ran into a MethodError.

Reading the comment in https://github.com/jonniedie/ComponentArrays.jl/blob/v0.15.2/src/array_interface.jl#L34-L35 I guess this may be of interest here. Defining the "possible fix" from the error below fixes it:

Base.vcat(x::AbstractVector{<:Number}, y::ComponentVector{<:Number}) = vcat(x, getdata(y))
ERROR: MethodError: vcat(::Vector{Float64}, ::ComponentArrays.ComponentVector{Float64, SubArray{Float64, 1, Vector{Float64}, Tuple{UnitRange{Int64}}, true}, Tuple{ComponentArrays.Axis{(cum_d_prec = 1, cum_d_rfal = 2, cum_d_sfal = 3, cum_d_rint = 4, cum_d_sint = 5, cum_d_rsno = 6, cum_d_rnet = 7, cum_d_smlt = 8, cum_d_evap = 9, cum_d_tran = 10, cum_d_irvp = 11, cum_d_isvp = 12, cum_d_slvp = 13, cum_d_snvp = 14, cum_d_pint = 15, cum_d_ptran = 16, cum_d_pslvp = 17, flow = 18, seep = 19, srfl = 20, slfl = 21, byfl = 22, dsfl = 23, gwfl = 24, vrfln = 25, cum_d_rthr = 26, cum_d_sthr = 27, StorageSWAT = 28, StorageWATER = 29, BALERD_SWAT = 30, BALERD_total = 31)}}}) is ambiguous.

Candidates:
  vcat(x::AbstractVector, y::ComponentArrays.ComponentVector)
    @ ComponentArrays C:\Users\visser_mn\.julia\dev\ComponentArrays\src\array_interface.jl:37
  vcat(X::Union{Number, AbstractVecOrMat{<:Number}}...)
    @ SparseArrays C:\Users\visser_mn\.julia\juliaup\julia-1.10.0-beta2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\SparseArrays\src\sparsevector.jl:1229

Possible fix, define
  vcat(::AbstractVector{<:Number}, ::ComponentArrays.ComponentVector{<:Number})

Stacktrace:
  [1] _mapreduce(f::typeof(identity), op::typeof(vcat), ::IndexLinear, A::Vector{Any})
    @ Base .\reduce.jl:443
  [2] _mapreduce_dim
    @ LWFBrook90 .\reducedim.jl:365 [inlined]
  [3] mapreduce
    @ LWFBrook90 .\reducedim.jl:357 [inlined]
  [4] reduce
    @ LWFBrook90 .\reducedim.jl:406 [inlined]
  [5] norm_to_use(u::ComponentArrays.ComponentVector{Float64, Vector{Float64}, Tuple{ComponentArrays.Axis{…}}}, t::Float64)
    @ LWFBrook90 C:\Users\visser_mn\.julia\packages\LWFBrook90\7uNU3\src\func_DiffEq_definition_ode.jl:23
  [6] __init(prob::SciMLBase.ODEProblem{…}, alg::OrdinaryDiffEq.Tsit5{…}, timeseries_init::Tuple{}, ts_init::Tuple{}, ks_init::Tuple{}, recompile::Type{…}; saveat::StepRangeLen{…}, tstops::Tuple{}, d_discontinuities::Tuple{}, save_idxs::Nothing, save_everystep::Bool, 
save_on::Bool, save_start::Bool, save_end::Nothing, callback::SciMLBase.CallbackSet{…}, dense::Bool, calck::Bool, dt::Float64, dtmin::Nothing, dtmax::Float64, force_dtmin::Bool, adaptive::Bool, gamma::Rational{…}, abstol::Nothing, reltol::Float64, qmin::Rational{…}, qmax::Int64, qsteady_min::Int64, qsteady_max::Int64, beta1::Nothing, beta2::Nothing, qoldinit::Rational{…}, controller::Nothing, fullnormalize::Bool, failfactor::Int64, maxiters::Int64, internalnorm::typeof(LWFBrook90.norm_to_use), internalopnorm::typeof(LinearAlgebra.opnorm), isoutofdomain::typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), unstable_check::typeof(LWFBrook90.unstable_check_function), verbose::Bool, timeseries_errors::Bool, dense_errors::Bool, advance_to_tstop::Bool, stop_at_next_tstop::Bool, initialize_save::Bool, progress::Bool, progress_steps::Int64, progress_name::String, progress_message::typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), userdata::Nothing, allow_extrapolation::Bool, initialize_integrator::Bool, alias_u0::Bool, alias_du0::Bool, initializealg::OrdinaryDiffEq.DefaultInit, kwargs::@Kwargs{…})
    @ OrdinaryDiffEq C:\Users\visser_mn\.julia\packages\OrdinaryDiffEq\NH6if\src\solve.jl:300

It looks like #169 is related, not sure if that also fixes the issue, the branch needs work.

visr avatar Sep 24 '23 08:09 visr

The underlying code in the package LWFBrook90.jl simplifies to the following MWE:

using ComponentArrays # version: [b0b7db55] ComponentArrays v0.15.2
u0 = ComponentArray(
    GWAT   = (mm = 0.0, d18O = 0.0, d2H = 0.0),
    INTS   = (mm = 0.0, d18O = 0.0, d2H = 0.0),
    INTR   = (mm = 0.0, d18O = 0.0, d2H = 0.0),
    accum  = (cum_d_prec = 0.0, ))
reduce(vcat, [u0.GWAT.mm, u0.INTS.mm, u0.INTR.mm])           # works
reduce(vcat, [u0.GWAT.mm, u0.INTS.mm, u0.INTR.mm, u0.accum]) # doesn't work

giving the error:

julia> reduce(vcat, [u0.GWAT.mm, u0.INTS.mm, u0.INTR.mm, u0.accum]) # doesn't work
ERROR: MethodError: vcat(::Vector{Float64}, ::ComponentVector{Float64, SubArray{Float64, 1, Vector{Float64}, Tuple{UnitRange{Int64}}, true}, Tuple{Axis{(cum_d_prec = 1,)}}}) is ambiguous.

Candidates:
  vcat(x::AbstractVector, y::ComponentVector)
    @ ComponentArrays ~/.julia/packages/ComponentArrays/NnCVQ/src/array_interface.jl:37
  vcat(X::Union{Number, AbstractVecOrMat{<:Number}}...)
    @ SparseArrays ~/.julia/juliaup/julia-1.10.0-beta2+0.x64.apple.darwin14/share/julia/stdlib/v1.10/SparseArrays/src/sparsevector.jl:1229

Possible fix, define
  vcat(::AbstractVector{<:Number}, ::ComponentVector{<:Number})

Stacktrace:
 [1] _mapreduce(f::typeof(identity), op::typeof(vcat), ::IndexLinear, A::Vector{Any})
   @ Base ./reduce.jl:443
 [2] _mapreduce_dim(f::Function, op::Function, ::Base._InitialValue, A::Vector{Any}, ::Colon)
   @ Base ./reducedim.jl:365
 [3] mapreduce
   @ Base ./reducedim.jl:357 [inlined]
 [4] reduce(op::Function, A::Vector{Any})
   @ Base ./reducedim.jl:406
 [5] top-level scope
   @ REPL[8]:1

fabern avatar Sep 25 '23 15:09 fabern

the vcat in v1.10 is breaking ReverseDiff too. https://github.com/JuliaDiff/ReverseDiff.jl/issues/242

prbzrg avatar Nov 21 '23 22:11 prbzrg