# DataInterpolations.jl - defining function without broadcasting syntax

I’m trying to fit a curve using DataInterpolations.jl and want to fit a curve with some fixed and variable parameters. The fixed number of terms can vary, which is why I’m starting with a sum of a generator (below, take `c` being `[0.2,0.4,0.6]` as the fixed parameters). I’m trying to figure out how to get this to work without needing to write out the full expression for different lengths of fixed `c` vectors.

``````m(x,params) = sum(params[i+1]*exp(-c*x) for (i,c) in enumerate([0.2,0.4,0.6])) + params[1]
rates =[0.01, 0.01, 0.03, 0.05, 0.07, 0.16, 0.35, 0.92, 1.40, 1.74, 2.31, 2.41] ./ 100
mats = [1/12, 2/12, 3/12, 6/12, 1, 2, 3, 5, 7, 10, 20, 30]
``````

Results in an error:

``````julia> Curvefit(rates,mats,m,ones(4),LBFGS())
ERROR: MethodError: no method matching exp(::Vector{Float64})
``````

If I write out the whole function explicitly with broadcasting syntax it works:

``````m(x, params) = @. params[1] + params[2]*exp(-0.2*x) + params[3] * exp(-0.4*x) + params[4] * exp(-0.8*x)
``````
``````julia> A = Curvefit(rates,mats,m,ones(4),LBFGS())
24-element DataInterpolations.CurvefitCache{Vector{Float64}, Vector{Float64}, typeof(m), Vector{Float64}, Nothing, Nothing, LBFGS{Nothing, LineSearches.InitialStatic{Float64}, LineSearches.HagerZhang{Float64, Base.RefValue{Bool}}, Optim.var"#19#21"}, Vector{Float64}, true, Float64}:
0.0001
0.0001
0.0003
0.0005
0.0007000000000000001
0.0016
0.0034999999999999996
⋮
2.0
3.0
5.0
7.0
10.0
20.0
30.0
``````

I tried writing a function that would return an array like I think the broadcasting version would do, but got an error as well:

``````m(x,params) = [sum(params[i+1]*exp(-c*x) for (i,c) in enumerate([0.2,0.4,0.6])) + params[1] for xi in x]
``````

And the assocated error:

``````julia> Curvefit(rates,mats,m,ones(4),LBFGS())
ERROR: MethodError: no method matching exp(::Vector{Float64})
``````

Are there suggested ways to do this?

This worked:

``````m(x,params) = sum(params[i+1]*exp.(-c.*x) for (i,c) in enumerate([0.2,0.4,0.6])) .+ params[1]
``````
1 Like