# LsqFit.curve\_fit not working

**URL:** <https://discourse.julialang.org/t/lsqfit-curve-fit-not-working/86705>\
**Category:** New to Julia\
**Created:** [September 2, 2022, 8:46pm UTC](https://discourse.julialang.org/t/lsqfit-curve-fit-not-working/86705 "2022-09-02T20:46:03Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![AwesomeQuest](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/awesomequest/32/38910_2.png) [@AwesomeQuest](https://discourse.julialang.org/u/AwesomeQuest)\
**Post date:** [September 2, 2022, 8:46pm UTC](https://discourse.julialang.org/t/lsqfit-curve-fit-not-working/86705/1 "2022-09-02T20:46:03Z")

</div>

What am I doing wrong here?

```julia
using LsqFit
polynom(x,p) = p[1].+p[2].*x
curve_fit(polynom, 1:100,polynom(1:100,[10 10]),[0.5 0.5])

```

And I get this error

```julia
ERROR: MethodError: no method matching levenberg_marquardt(::NLSolversBase.OnceDifferentiable{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, Matrix{Float64}, Matrix{Float64}}, ::Matrix{Float64})

You might have used a 2d row vector where a 1d column vector was required.
Note the difference between 1d column vector [1,2,3] and 2d row vector [1 2 3].
You can convert to a column vector with the vec() function.
Closest candidates are:
  levenberg_marquardt(::NLSolversBase.OnceDifferentiable, ::AbstractVector{T}; x_tol, g_tol, maxIter, lambda, tau, lambda_increase, lambda_decrease, min_step_quality, good_step_quality, show_trace, lower, upper, avv!) where T at C:\Users\torfi\.julia\packages\LsqFit\hgZQe\src\levenberg_marquardt.jl:34
Stacktrace:
 [1] lmfit(R::NLSolversBase.OnceDifferentiable{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, Matrix{Float64}, Matrix{Float64}}, p0::Matrix{Float64}, wt::Vector{Int64}; autodiff::Symbol, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ LsqFit C:\Users\torfi\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:68
 [2] lmfit(R::NLSolversBase.OnceDifferentiable{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, Matrix{Float64}, Matrix{Float64}}, p0::Matrix{Float64}, wt::Vector{Int64})
   @ LsqFit C:\Users\torfi\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:68
 [3] lmfit(f::LsqFit.var"#18#20"{typeof(polynom), UnitRange{Int64}, StepRangeLen{Int64, Int64, Int64, Int64}}, p0::Matrix{Float64}, wt::Vector{Int64}; autodiff::Symbol, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ LsqFit C:\Users\torfi\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:64
 [4] lmfit(f::Function, p0::Matrix{Float64}, wt::Vector{Int64})
   @ LsqFit C:\Users\torfi\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:61
 [5] curve_fit(model::typeof(polynom), xdata::UnitRange{Int64}, ydata::StepRangeLen{Int64, Int64, Int64, Int64}, p0::Matrix{Float64}; inplace::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ LsqFit C:\Users\torfi\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:115
 [6] curve_fit(model::Function, xdata::UnitRange{Int64}, ydata::StepRangeLen{Int64, Int64, Int64, Int64}, p0::Matrix{Float64})
   @ LsqFit C:\Users\torfi\.julia\packages\LsqFit\hgZQe\src\curve_fit.jl:106
 [7] top-level scope
   @ REPL[3]:1

```

Shouldn’t this just work? To use a function to fit to the output of that function? I am so confused.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [September 2, 2022, 8:52pm UTC](https://discourse.julialang.org/t/lsqfit-curve-fit-not-working/86705/2 "2022-09-02T20:52:40Z")

</div>

The method `levenberg_marquardt` wants a column `Vector` for its input. You’re supplying a row vector in the form of a `Matrix`, a 2D-Array.

Observe the difference below:

```julia
julia> [10 10]
1×2 Matrix{Int64}:
 10 10

julia> [10, 10]
2-element Vector{Int64}:
 10
 10

```

Try this

```julia
using LsqFit
polynom(x,p) = p[1].+p[2].*x
result = curve_fit(polynom, collect(1:100) ,polynom(1:100,[10, 10]),[0.5, 0.5]);
result.param

julia> result.param
2-element Vector{Float64}:
 10.000000000000025
 10.0

```

I agree though. This should be more flexible and user friendly.

---

<div class="post-metadata">

**Author:** ![AwesomeQuest](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/awesomequest/32/38910_2.png) [@AwesomeQuest](https://discourse.julialang.org/u/AwesomeQuest)\
**Post date:** [September 2, 2022, 10:31pm UTC](https://discourse.julialang.org/t/lsqfit-curve-fit-not-working/86705/3 "2022-09-02T22:31:54Z")

</div>

Thank you sososo much! When I send both my x and y data through collect first it works!  
I feel like I need to make a bug report though. Because it seems to me that this problem is literally impossible to debug in my case.  
You see, when I do a typeof for the data I was trying to send to curve\_fit I get `Vector{Int64} (alias for Array{Int64, 1})` and when I wrap it in `collect()` I also get `Vector{Int64} (alias for Array{Int64, 1})` . The two are identical as far as I can tell. What’s changing? Since one works and one doesn’t.

What else can I look out for in the future?

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [September 2, 2022, 10:52pm UTC](https://discourse.julialang.org/t/lsqfit-curve-fit-not-working/86705/4 "2022-09-02T22:52:30Z")

</div>

```julia
julia> typeof(1:100)
UnitRange{Int64}

julia> typeof(collect(1:100))
Vector{Int64} (alias for Array{Int64, 1})

```

The type changes here.

Note that I changed two things:

1. I added commas in the array literals them a `Vector` instead of a `Matrix`.
2. I added `collect` to make the `UnitRange` a `Vector`.

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [September 3, 2022, 3:58pm UTC](https://discourse.julialang.org/t/lsqfit-curve-fit-not-working/86705/5 "2022-09-03T15:58:37Z")

</div>

> [@AwesomeQuest](#):
>
> I feel like I need to make a bug report though.
> 
> What else can I look out for in the future?

This is almost certainly a bug in LsqFit.jl, so I’ll encourage you to file it (referencing this thread).

`curve_fit` is written to accept any `AbstractArray` type for its second argument, which are things that behave like arrays, include ranges like `1:100` as in your case. But then, internally, it seems like it tries to assign to (a copy of) that argument - you can’t assign to ranges, hence your error.

@mkitti 's suggestion to use `collect` changes `1:100` into `[1, 2, 3, 4, ... 98, 99, 100]` i.e. it changes the `Range` into a `Vector` type, which _can_ be assigned to, so `curve_fit` no longer errors. However, this shouldn’t be necessary since it should work for any `AbstractArray` subtype, so should be considered a bug in `curve_fit`.

`collect` takes anything that can be iterated upon, and converts it into a `Vector` by allocating memory for all elements of the iterator. Generally, using `collect` is a bad habit that newcomers in Julia sometimes pick up, just because it produces nicer, easier-to-understand output in the REPL compared to many iterators. However, in many cases you can use the `Range` or other iterator directly in your code, pass it as arguments to other functions, etc. It’s unfortunate that you encountered this bug that requires a `collect` to solve, but keep in mind that in general, using `collect` unnecessarily can allocate a lot of memory and slow down your code.
