# Curve fitting with LsqFit

**URL:** <https://discourse.julialang.org/t/curve-fitting-with-lsqfit/27685>\
**Category:** New to Julia\
**Created:** [August 18, 2019, 6:45pm UTC](https://discourse.julialang.org/t/curve-fitting-with-lsqfit/27685 "2019-08-18T18:45:31Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![KirillGerke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kirillgerke/32/11383_2.png) [@KirillGerke](https://discourse.julialang.org/u/KirillGerke)\
**Post date:** [August 18, 2019, 6:45pm UTC](https://discourse.julialang.org/t/curve-fitting-with-lsqfit/27685/1 "2019-08-18T18:45:32Z")

</div>

Dear All,

My aim is to fit some real data with a pretty complex curve representing a superposition of dumping, oscillating and other simple ‘sub-curves’. I use LsqFit. Here is the code example:

```julia
using LsqFit
  
model(t, p) = p[1] * exp.(-p[2] * t)
    model1(t, p) = p[1] * exp.(-p[2] * t) + p[3] * exp.(-p[4] * t) * cos.(p[5] * t + p[6])
    # x data
    tdata = range(0,stop=10,length=20)
    # func data
    ydata = model(tdata, [1.0 2.0]) + 0.01*randn(length(tdata))
    p0 = [0.5, 0.5 ,0.5, 0.5, 0.5, 0.5]
    fit = curve_fit(model1, tdata, ydata, p0)
    param = fit.param

```

The example with model works just fine, but if now change it to something i want, e.g., model1 - i get something like this:

```julia
julia> fit = curve_fit(model1, tdata, ydata, p0)
ERROR: MethodError: no method matching +(::Array{Float64,1}, ::Float64)
Closest candidates are:
  +(::Any, ::Any, ::Any, ::Any...) at operators.jl:502
  +(::Bool, ::T<:AbstractFloat) where T<:AbstractFloat at bool.jl:112
  +(::Float64, ::Float64) at float.jl:395

```

Many thanks in advance for any tips/solutions!

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [August 18, 2019, 6:58pm UTC](https://discourse.julialang.org/t/curve-fitting-with-lsqfit/27685/2 "2019-08-18T18:58:04Z")

</div>

You just need some more `.`s:

```julia
model1(t, p) = p[1] * exp.(-p[2] * t) .+ p[3] * exp.(-p[4] * t) .* cos.(p[5] * t .+ p[6])

```

or

```julia
model1(t, p) = @.(p[1] * exp(-p[2] * t) + p[3] * exp(-p[4] * t) * cos(p[5] * t + p[6]))

```

---

<div class="post-metadata">

**Author:** ![KirillGerke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kirillgerke/32/11383_2.png) [@KirillGerke](https://discourse.julialang.org/u/KirillGerke)\
**Post date:** [August 18, 2019, 7:12pm UTC](https://discourse.julialang.org/t/curve-fitting-with-lsqfit/27685/3 "2019-08-18T19:12:23Z")

</div>

Thank you, Sebastian!  
It works now, but could you, please, however briefly, explain why it works (in both cases preferably).  
At first glance my model1 is basically the same as model in examples…  
All the best,  
K.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [August 18, 2019, 7:40pm UTC](https://discourse.julialang.org/t/curve-fitting-with-lsqfit/27685/4 "2019-08-18T19:40:33Z")

</div>

Take a look at the [docs about vectorized functions](https://docs.julialang.org/en/v1.1/manual/functions/#man-vectorized-1).

---

<div class="post-metadata">

**Author:** ![KirillGerke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kirillgerke/32/11383_2.png) [@KirillGerke](https://discourse.julialang.org/u/KirillGerke)\
**Post date:** [August 22, 2019, 8:23am UTC](https://discourse.julialang.org/t/curve-fitting-with-lsqfit/27685/5 "2019-08-22T08:23:40Z")

</div>

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:

```julia
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:

```julia
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 for tips.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [August 22, 2019, 8:28am UTC](https://discourse.julialang.org/t/curve-fitting-with-lsqfit/27685/6 "2019-08-22T08:28:07Z")

</div>

The ternary operator doesn’t particaipate in broadcasting, but you can just use `ifelse` instead:

```julia
model1(t, p) = @.(p[1] * exp(-p[2] * t) + p[3] * exp(-p[4] * t) * cos(p[5] * t + p[6])+ p[7] * ifelse(t > p[8], 0, (1 - t / p[8])^2))

```

This does have some implications you should be aware of:

```julia
help?> ifelse
search: ifelse

  ifelse(condition::Bool, x, y)

  Return x if condition is true, otherwise return y. This differs from ? or if in that it is an ordinary function, so all the arguments are evaluated first. In some cases, using ifelse instead of an if statement
  can eliminate the branch in generated code and provide higher performance in tight loops.

```
