Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for ComponentArrays #240

Open
1991jhf opened this issue Aug 4, 2023 · 3 comments
Open

Support for ComponentArrays #240

1991jhf opened this issue Aug 4, 2023 · 3 comments

Comments

@1991jhf
Copy link

1991jhf commented Aug 4, 2023

is it possible to support componet array for parameters?
if i have variable number of parameters, it will be diffucult to track their positions.
It will be nice if i make p0 a component array and get optimized param with same shape.

@lamont-granquist
Copy link

lamont-granquist commented Aug 22, 2023

It seems to not be working for me:

using LsqFit
using ComponentArrays
using Parameters: @unpack

# solve J=1/2x^2+1/2y^2 subject to x + y = 2
function root!(z, ignored, u)
    println(u)
    @unpack x, y, λ = u
    z.∂L∂λ = x + y - 2.0
    z.∂L∂x = x - λ
    z.∂L∂y = y - λ
    println(z)
    return nothing
end

u0 = ComponentArray(x = 0.0, y = 0.0, λ = 0.0)
z = ComponentArray(∂L∂λ = 0.0, ∂L∂x = 0.0, ∂L∂y = 0.0)
sol = curve_fit(root!, [0.0], z, u0; inplace=true)

that throws in FiniteDiff.jl, I also get a failure by adding autodiff=:forwarddiff as well (which may be blowing up in LsqFit instead), I'm not sure which component it would be most useful to cut an issue against.

MethodError: no method matching reshape(::UnitRange{Int64}, ::Tuple{ComponentArrays.CombinedAxis{Axis{(x = 1, y = 2, λ = 3)}, Base.OneTo{Int64}}})

Closest candidates are:
  reshape(::AbstractVector, ::Colon)
   @ Base reshapedarray.jl:115
  reshape(::AbstractVector, ::Tuple{Colon})
   @ Base reshapedarray.jl:116
  reshape(::AbstractArray{T, N}, ::Val{N}) where {T, N}
   @ Base reshapedarray.jl:140
  ...


Stacktrace:
  [1] reshape(parent::UnitRange{Int64}, dims::ComponentArrays.CombinedAxis{Axis{(x = 1, y = 2, λ = 3)}, Base.OneTo{Int64}})
    @ Base ./reshapedarray.jl:110
  [2] finite_difference_jacobian!(J::ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, f::LsqFit.var"#17#19"{typeof(root!), Vector{Float64}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}}, x::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, cache::FiniteDiff.JacobianCache{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, UnitRange{Int64}, Nothing, Val{:central}(), Float64}, f_in::Nothing; relstep::Float64, absstep::Float64, colorvec::UnitRange{Int64}, sparsity::Nothing, dir::Bool)
    @ FiniteDiff ~/.julia/packages/FiniteDiff/grio1/src/jacobians.jl:354
  [3] finite_difference_jacobian!(J::ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, f::Function, x::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, cache::FiniteDiff.JacobianCache{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, UnitRange{Int64}, Nothing, Val{:central}(), Float64}, f_in::Nothing)
    @ FiniteDiff ~/.julia/packages/FiniteDiff/grio1/src/jacobians.jl:341
  [4] finite_difference_jacobian!(J::ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, f::Function, x::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, cache::FiniteDiff.JacobianCache{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, UnitRange{Int64}, Nothing, Val{:central}(), Float64})
    @ FiniteDiff ~/.julia/packages/FiniteDiff/grio1/src/jacobians.jl:341
  [5] (::NLSolversBase.var"#fj_finitediff!#21"{LsqFit.var"#17#19"{typeof(root!), Vector{Float64}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}}, FiniteDiff.JacobianCache{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, UnitRange{Int64}, Nothing, Val{:central}(), Float64}})(F::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, J::ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, x::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}})
    @ NLSolversBase ~/.julia/packages/NLSolversBase/kavn7/src/objective_types/oncedifferentiable.jl:139
  [6] value_jacobian!!(obj::NLSolversBase.OnceDifferentiable{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}}, F::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, J::ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, x::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}})
    @ NLSolversBase ~/.julia/packages/NLSolversBase/kavn7/src/interface.jl:124
  [7] value_jacobian!!
    @ ~/.julia/packages/NLSolversBase/kavn7/src/interface.jl:122 [inlined]
  [8] levenberg_marquardt(df::NLSolversBase.OnceDifferentiable{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}}, initial_x::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}; x_tol::Float64, g_tol::Float64, maxIter::Int64, lambda::Float64, tau::Float64, lambda_increase::Float64, lambda_decrease::Float64, min_step_quality::Float64, good_step_quality::Float64, show_trace::Bool, lower::Vector{Float64}, upper::Vector{Float64}, avv!::Nothing)
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/levenberg_marquardt.jl:42
  [9] levenberg_marquardt(df::NLSolversBase.OnceDifferentiable{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}}, initial_x::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}})
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/levenberg_marquardt.jl:34
 [10] lmfit(R::NLSolversBase.OnceDifferentiable{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}}, p0::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, wt::Vector{Float64}; autodiff::Symbol, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/curve_fit.jl:68
 [11] lmfit(R::NLSolversBase.OnceDifferentiable{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}}, p0::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, wt::Vector{Float64})
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/curve_fit.jl:67
 [12] lmfit(f::Function, p0::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, wt::Vector{Float64}, r::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}; autodiff::Symbol, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/curve_fit.jl:43
 [13] lmfit(f::Function, p0::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, wt::Vector{Float64}, r::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}})
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/curve_fit.jl:41
 [14] curve_fit(model::typeof(root!), xdata::Vector{Float64}, ydata::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, p0::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}; inplace::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/curve_fit.jl:115
 [15] top-level scope
    @ In[7]:1

@lamont-granquist
Copy link

The error when using ForwardDiff.jl:

ArgumentError: No method is implemented for reducing index range of type ComponentArrays.CombinedAxis{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Base.OneTo{Int64}}. Please implement
reduced_index for this index type or report this as an issue.


Stacktrace:
  [1] reduced_index(i::ComponentArrays.CombinedAxis{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Base.OneTo{Int64}})
    @ Base ./reducedim.jl:8
  [2] reduced_indices(inds::Tuple{ComponentArrays.CombinedAxis{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Base.OneTo{Int64}}, ComponentArrays.CombinedAxis{Axis{(x = 1, y = 2, λ = 3)}, Base.OneTo{Int64}}}, d::Int64)
    @ Base ./reducedim.jl:23
  [3] reduced_indices
    @ ./reducedim.jl:15 [inlined]
  [4] reducedim_initarray(A::ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, region::Int64, init::Float64, #unused#::Type{Float64})
    @ Base ./reducedim.jl:91
  [5] reducedim_initarray
    @ ./reducedim.jl:92 [inlined]
  [6] reducedim_init
    @ ./reducedim.jl:219 [inlined]
  [7] _mapreduce_dim
    @ ./reducedim.jl:371 [inlined]
  [8] #mapreduce#800
    @ ./reducedim.jl:357 [inlined]
  [9] mapreduce
    @ ./reducedim.jl:357 [inlined]
 [10] #_sum#834
    @ ./reducedim.jl:1023 [inlined]
 [11] _sum
    @ ./reducedim.jl:1023 [inlined]
 [12] #sum#808
    @ ./reducedim.jl:995 [inlined]
 [13] sum
    @ ./reducedim.jl:995 [inlined]
 [14] levenberg_marquardt(df::NLSolversBase.OnceDifferentiable{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}}, initial_x::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}; x_tol::Float64, g_tol::Float64, maxIter::Int64, lambda::Float64, tau::Float64, lambda_increase::Float64, lambda_decrease::Float64, min_step_quality::Float64, good_step_quality::Float64, show_trace::Bool, lower::Vector{Float64}, upper::Vector{Float64}, avv!::Nothing)
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/levenberg_marquardt.jl:110
 [15] levenberg_marquardt(df::NLSolversBase.OnceDifferentiable{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}}, initial_x::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}})
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/levenberg_marquardt.jl:34
 [16] lmfit(R::NLSolversBase.OnceDifferentiable{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}}, p0::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, wt::Vector{Float64}; autodiff::Symbol, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/curve_fit.jl:68
 [17] lmfit(R::NLSolversBase.OnceDifferentiable{ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, ComponentMatrix{Float64, Matrix{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}, Axis{(x = 1, y = 2, λ = 3)}}}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}}, p0::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, wt::Vector{Float64})
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/curve_fit.jl:67
 [18] lmfit(f::Function, p0::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}, wt::Vector{Float64}, r::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}; autodiff::Symbol, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/curve_fit.jl:43
 [19] curve_fit(model::typeof(root!), xdata::Vector{Float64}, ydata::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(∂L∂λ = 1, ∂L∂x = 2, ∂L∂y = 3)}}}, p0::ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(x = 1, y = 2, λ = 3)}}}; inplace::Bool, kwargs::Base.Pairs{Symbol, Symbol, Tuple{Symbol}, NamedTuple{(:autodiff,), Tuple{Symbol}}})
    @ LsqFit ~/.julia/packages/LsqFit/BBrNp/src/curve_fit.jl:115
 [20] top-level scope
    @ In[6]:1

@pkofod
Copy link
Member

pkofod commented Oct 12, 2023

is it possible to support componet array for parameters?
if i have variable number of parameters, it will be diffucult to track their positions.
It will be nice if i make p0 a component array and get optimized param with same shape.

If you give me an example of a model and the input you want to give, I can have a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants