Confusing dimension mismatch error

I am trying to extract fitting parameters, but I am unable to understand the error, it looks like dimensions are same. Both En and abs are row vector of size 601.

using LsqFit, DataFrames,DelimitedFiles, QuadGK

α(E,p) = ( p[1].*sqrt(p[2])./(E.*(2π) )).*(sum(m-> (2*p[2]/(m^3))*(1/p[4])*exp(-((E .- (p[3] - p[2]/(m^2)))^2)/(2*(p[4]^2))),1:1000  ) .+ (1/p[5]).*quadgk(x-> exp.(-(x .- E).^2/(2*p[5].^2))./(1 .- exp.(-2π*sqrt(p[2]./(x .- p[3]))) ),p[3],Inf,rtol=1e-3 )  )

p0=[1e+6,0.08,5.1,0.2,0.2]

fit=curve_fit(α,En,abs,p0)

DimensionMismatch("A has dimensions (1,601) but B has dimensions (1,601)")

Stacktrace:
  [1] gemm_wrapper!(C::Matrix{Float64}, tA::Char, tB::Char, A::Matrix{Float64}, B::Matrix{Float64}, _add::LinearAlgebra.MulAddMul{true, true, Bool, Bool})
    @ LinearAlgebra C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\matmul.jl:643
  [2] mul!
    @ C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\matmul.jl:169 [inlined]
  [3] mul!
    @ C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\matmul.jl:275 [inlined]
  [4] *
    @ C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\matmul.jl:160 [inlined]
  [5] power_by_squaring(x_::Matrix{Float64}, p::Int64)
    @ Base .\intfuncs.jl:262
  [6] ^
    @ C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\dense.jl:442 [inlined]
  [7] macro expansion
    @ .\none:0 [inlined]
  [8] literal_pow
    @ .\none:0 [inlined]
  [9] (::var"#11#13"{LinearAlgebra.Transpose{Float64, Vector{Float64}}, Vector{Float64}})(m::Int64)
    @ Main .\In[20]:1
 [10] mapreduce_impl(f::var"#11#13"{LinearAlgebra.Transpose{Float64, Vector{Float64}}, Vector{Float64}}, op::typeof(Base.add_sum), A::UnitRange{Int64}, ifirst::Int64, ilast::Int64, blksize::Int64)
    @ Base .\reduce.jl:242
 [11] mapreduce_impl
    @ .\reduce.jl:257 [inlined]
 [12] _mapreduce(f::var"#11#13"{LinearAlgebra.Transpose{Float64, Vector{Float64}}, Vector{Float64}}, op::typeof(Base.add_sum), #unused#::IndexLinear, A::UnitRange{Int64})
    @ Base .\reduce.jl:415
 [13] _mapreduce_dim
    @ .\reducedim.jl:318 [inlined]
 [14] #mapreduce#672
    @ .\reducedim.jl:310 [inlined]
 [15] mapreduce
    @ .\reducedim.jl:310 [inlined]
 [16] #_sum#682
    @ .\reducedim.jl:878 [inlined]
 [17] _sum
    @ .\reducedim.jl:878 [inlined]
 [18] #sum#680
    @ .\reducedim.jl:874 [inlined]
 [19] sum
    @ .\reducedim.jl:874 [inlined]
 [20] α(E::LinearAlgebra.Transpose{Float64, Vector{Float64}}, p::Vector{Float64})
    @ Main .\In[20]:1
 [21] #18
    @ C:\Users\usmaa\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:114 [inlined]
 [22] lmfit(f::LsqFit.var"#18#20"{typeof(α), LinearAlgebra.Transpose{Float64, Vector{Float64}}, Vector{Float64}}, p0::Vector{Float64}, wt::Vector{Float64}; autodiff::Symbol, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ LsqFit C:\Users\usmaa\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:61
 [23] lmfit
    @ C:\Users\usmaa\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:61 [inlined]
 [24] curve_fit(model::typeof(α), xdata::LinearAlgebra.Transpose{Float64, Vector{Float64}}, ydata::Vector{Float64}, p0::Vector{Float64}; inplace::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ LsqFit C:\Users\usmaa\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:115
 [25] curve_fit(model::Function, xdata::LinearAlgebra.Transpose{Float64, Vector{Float64}}, ydata::Vector{Float64}, p0::Vector{Float64})
    @ LsqFit C:\Users\usmaa\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:106
 [26] top-level scope
    @ In[20]:3
 [27] eval
    @ .\boot.jl:360 [inlined]
 [28] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
    @ Base .\loading.jl:1116

I think this is the same issue as here: Error in mul!(c,a,b) if size(b) = (n,1) - #8 by lmiq

tl;dr is that LsqFit’s functions accept anything, but they only actually work with vector input. You probably want to call vec(p0) before passing it in, and make sure your function En accepts that.

1 Like

@mcabbott Thanks for the quick reply, I tried to vectorize the input but now it gives another dimension mismatch error.

fit=curve_fit(α,vec(En),abs,p0)

DimensionMismatch("arrays could not be broadcast to a common size; got a dimension with lengths 601 and 2")
Stacktrace:
  [1] _bcs1
    @ .\broadcast.jl:501 [inlined]
  [2] _bcs
    @ .\broadcast.jl:495 [inlined]
  [3] broadcast_shape
    @ .\broadcast.jl:489 [inlined]
  [4] combine_axes
    @ .\broadcast.jl:484 [inlined]
  [5] _axes
    @ .\broadcast.jl:209 [inlined]
  [6] axes
    @ .\broadcast.jl:207 [inlined]
  [7] combine_axes
    @ .\broadcast.jl:484 [inlined]
  [8] instantiate
    @ .\broadcast.jl:266 [inlined]
  [9] materialize
    @ .\broadcast.jl:883 [inlined]
 [10] α(E::Vector{Float64}, p::Vector{Float64})
    @ Main .\In[30]:3
 [11] #18
    @ C:\Users\usmaa\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:114 [inlined]
 [12] lmfit(f::LsqFit.var"#18#20"{typeof(α), Vector{Float64}, Vector{Float64}}, p0::Vector{Float64}, wt::Vector{Float64}; autodiff::Symbol, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ LsqFit C:\Users\usmaa\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:61
 [13] lmfit
    @ C:\Users\usmaa\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:61 [inlined]
 [14] curve_fit(model::typeof(α), xdata::Vector{Float64}, ydata::Vector{Float64}, p0::Vector{Float64}; inplace::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ LsqFit C:\Users\usmaa\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:115
 [15] curve_fit(model::Function, xdata::Vector{Float64}, ydata::Vector{Float64}, p0::Vector{Float64})
    @ LsqFit C:\Users\usmaa\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:106
 [16] top-level scope
    @ In[32]:1
 [17] eval
    @ .\boot.jl:360 [inlined]
 [18] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
    @ Base .\loading.jl:1116

I know my input arrays are of length 601, what dimension this 2 represents here

The 2 is surprising, I don’t know!

Maybe add some fake data (and triple-backticks ``` around code) to the example? It’s easier for people to help if this can be run on a fresh session.

2 Likes

Thanks have resolved the issue, 2 was because of quadgk. But I think LsqFit.jl is not a good package for this kind of curve fit and parameter extraction exercise, could you suggest any other julia package for the same

You could create a MWE providing for instance En and abs of small sizes, say 10.

@rafael.guerra what is MWE

Please read here.

1 Like

Thanks all, i have solved my problem. Normallization works here to get it converged, normallize so that all parameters are in the similar range.