# Function generating functions

Hello together,

Maybe this question is kind of trivial, but since I’m a Julia newbie I hoped to find some help and/or advice here. I would like to fit different functions to some data. They only differ by one parameter `k`. The following code does not run. It is rather a “statement of intent” to explain what my goal is:

``````function model(x, p, k)
sum([p[i]*(x.^i/factorial(i)) for i in 1:k])
end

for i in 1:10
fit = curve_fit(model(.,.,i), x, y)
... some more code ...
end
``````

It worked to a point, where different …things where generate ( of type `var"#574#576"`) These objects can be evaluated and yield some value if provided with arguments. But the `curve_fit` function does not like this type of object. I tried to use something like:

``````function m(k)
return :((x,p) -> sum([p[i]*(x.^i./factorial(i)) for i in 1:k]))
end

for l in 1:10
curve_fit(eval(m(l)), x, y)
... some code ...
end
``````

I’d appreciate if someone could help me with this.

I think you nearly had it, but tried to make it more complicated than needed. If I get your point, you don’t really need metaprogramming (`eval` expressions, etc.) Just returning an anonymous function should be fine:

``````function m(k)
return (x,p) -> sum([p[i]*(x.^i./factorial(i)) for i in 1:k])
end

for l in 1:10
curve_fit(m(l), x, y)
... some code ...
end
``````
2 Likes

As a new user, I’d also like to point out that use a comprehension with the `[ ]` isn’t necessary, and you can instead use the generator expression. So instead, you would do `sum(p[i]*(x.^i./factorial(i)) for i in 1:k)`. Notice the brackets were removed. https://docs.julialang.org/en/v1/manual/arrays/#Generator-Expressions-1

With the array comprehension with the brackets, the vector is allocated memory, calculated for each element, then it is summed. With the generated expression, it is calculated and summed without allocating any memory.

4 Likes

@heliosdrm thank you. I tried it, but the `curve_fit` function form `LsqFit.jl` can not handle this kind of return type. At least it gives me the following error:

``````MethodError: no method matching curve_fit(::var"#50#52"{Int64}, ::Array{Int64,1}, ::Array{Float64,1})
Closest candidates are:
curve_fit(::Any, ::AbstractArray, ::AbstractArray, !Matched::AbstractArray{T,2}, !Matched::Any; kwargs...) where T at /home/yannick/.julia/packages/LsqFit/NjkFI/src/curve_fit.jl:168
curve_fit(::Any, ::AbstractArray, ::AbstractArray, !Matched::AbstractArray; inplace, kwargs...) at /home/yannick/.julia/packages/LsqFit/NjkFI/src/curve_fit.jl:106
curve_fit(::Any, ::AbstractArray, ::AbstractArray, !Matched::AbstractArray{T,N} where N, !Matched::AbstractArray; inplace, kwargs...) where T at /home/yannick/.julia/packages/LsqFit/NjkFI/src/curve_fit.jl:137
...
``````

Maybe this problem is related to the fact that the `curve_fit` function expects as first input a function, which returns any `Float` or `Int` type, but when I try

``````ptintln(m(2)([1 2 3], [1 2]))
``````

an array is returned.

Edit: Never mide.Of cource it should give an array if the `x` input is an array. But the error still bothers me…

@Daniel_Berge Ahh, quite intresting to know, thanks.

I don’t know the details of `LsqFit.jl`, but looking at the documentation of `curve_fit` and the error you cite, I’d say that its primary cause is that `curve_fit` needs four arguments, and you are only passing three.

Well, this is rather stupid mistake. Thank you for pointing it out.