# Question: Least square fitting method for non-linear function

**URL:** https://discourse.julialang.org/t/question-least-square-fitting-method-for-non-linear-function/97595
**Category:** General Usage
**Tags:** question, lsqfit
**Created:** [April 18, 2023, 12:46am UTC](https://discourse.julialang.org/t/question-least-square-fitting-method-for-non-linear-function/97595 "2023-04-18T00:46:44Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![manu\_han](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/manu_han/32/47520_2.png) [@manu\_han](https://discourse.julialang.org/u/manu_han)
#### Post date: [April 18, 2023, 12:46am UTC](https://discourse.julialang.org/t/question-least-square-fitting-method-for-non-linear-function/97595/1 "2023-04-18T00:46:44Z")

</div>

To fit the non-linear function with other data, I am trying to use the ‘LsqFit.curve\_fit’ which was introduced by the following link: [GitHub - JuliaNLSolvers/LsqFit.jl: Simple curve fitting in Julia](https://github.com/JuliaNLSolvers/LsqFit.jl)

here is toy example:

```julia
using DelimitedFiles, Plots, Serialization, Transducers, Match, LsqFit, Dierckx
        #meta=deserialize("meta_SPS.bin");
	 meta=rand(55,27,150) #same type with real meta
        #Fv_NOC=deserialize("Fv_NOC.bin");
	 Fv_NOC=rand(200,3,55) #same type with real meta
        meta_start=395; meta_end=400; meta_div=trunc(Int,((meta_end-meta_start)*100)); #
        meta_cal=LinRange(meta_start,meta_end,meta_div);
            I_sharp=Array{Float64,2}(undef,150,27);
            I_broad=zeros(Float64, meta_div)
            obs_metaq=LinRange(394,402,205); obs_Iq=LinRange(100,1000,205);
            function OTrans(meta, meta_shift, Holn, Fv_NOC, p)
                Translation=p
                for brazera=1:27;
                    for J1=1:150
                        I_sharp[J1,brazera]=(1/(meta[J1,brazera,numb_v].-meta_shift[numb_v])^4)*Holn[J1,brazera]*exp(-2.2/Translation)
                        I_broad.+= I_sharp[J1,brazera].*exp.(-2 .*( meta_cal .-(meta[J1,brazera,numb_v])).^2)
                    end 
                end
                return I_broad
            end
            interpolation=Spline1D(obs_metaq, obs_Iq, k=1)
            Int_Iq=interpolation(meta_cal) #Finding query points
            p0=Float64.([300])
            fit=LsqFit.curve_fit(OTrans,meta_cal,Int_Iq,p0)

```

I made a code similar to the example introduced, but it didn’t work leaving an error like the following message:

```julia
ERROR: MethodError: no method matching OTrans(::LinRange{Float64, Int64}, ::Vector{Float64})
Closest candidates are:
  OTrans(::Any) at Toy_example.jl:48
Stacktrace:
 [1] (::LsqFit.var"#18#20"{typeof(OTrans), LinRange{Float64, Int64}, Vector{Float64}})(p::Vector{Float64})

```

How can I get this to work? or any other method?

---

<div class="post-metadata">

### Author: ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)
#### Post date: [April 18, 2023, 9:39am UTC](https://discourse.julialang.org/t/question-least-square-fitting-method-for-non-linear-function/97595/2 "2023-04-18T09:39:05Z")

</div>

It looks like `LsqFit.curve_fit` expects the model function you want to minimize as first argument, but the arguments of this `model` function have to have a specific signature.

In your example, `OTrans` requires five arguments, but the model function has to accept two arguments with a specific meaning. This is documented here

> **[GitHub - JuliaNLSolvers/LsqFit.jl: Simple curve fitting in Julia](https://github.com/JuliaNLSolvers/LsqFit.jl#existing-functionality)**
>
> Simple curve fitting in Julia. Contribute to JuliaNLSolvers/LsqFit.jl development by creating an account on GitHub.

If you want to keep your `OTrans` function as it is, one possibility would be to define another function with the right signature that internally calls `OTrans` in the right way. Something like

```julia
OTrans(#= different arguments here =#) = ...
model(x, p) = OTrans(#= use x, p to compute the right arguments for OTrans =#)

```

Aside: Your code is formatted in a pretty weird way which makes it hard to see what is going on. To make it easier for yourself and others, you might want to format the code a bit (e.g. put statements in the same scope at the same indentation level).

---

<div class="post-metadata">

### Author: ![manu\_han](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/manu_han/32/47520_2.png) [@manu\_han](https://discourse.julialang.org/u/manu_han)
#### Post date: [June 6, 2023, 6:47am UTC](https://discourse.julialang.org/t/question-least-square-fitting-method-for-non-linear-function/97595/3 "2023-06-06T06:47:32Z")

</div>

As follow your comment, I put an argument as an array having 4 elements.  
But it doesn’t work with the error as follows: MethodError: no method matching isinf(::Array{Float64, 3}).  
Cite: [How to use the array as the argument for curve-fit?](https://discourse.julialang.org/t/how-to-use-the-array-as-the-argument-for-curve-fit/99802)  
Is there a way to solve this problem?

other posts I cited:

> [@Curve fitting with LsqFit](https://discourse.julialang.org/t/curve-fitting-with-lsqfit/27685/5):
>
> Thank you! It is much clearer now. Yet, there is a new problem. Now i am trying to use a complex function with ternary operator: model1(t, p) = @.(p[1] \* exp(-p[2] \* t) + p[3] \* exp(-p[4] \* t) \* cos(p[5] \* t + p[6])+ p[7] \* (t \> p[8] ? 0 : (1 - t / p[8])^2)) The error i get is the following: ERROR: TypeError: non-boolean (BitArray{1}) used in boolean context Stacktrace: [1] model1(::Array{Int64,1}, ::Array{Float64,1}) at .\REPL[184]:1 [2] top-level scope at none:0 Many thanks in advance f…

> [@\[ANN\] JSON3.jl - Yet another JSON package for Julia](https://discourse.julialang.org/t/ann-json3-jl-yet-another-json-package-for-julia/25625/6):
>
> Nice, in that case the only thing I’d have done differently would be to have it fail more for other types.
