Can't fit nonlinear function including '^' in LsqFit

Hi there,

When I try to fit to a concentration-response curve (Hill equation) and use the exponent as a free parameter, Julia throws me an error complaining that the base should be a complex number. Even using lower bounds for curve_fit that prohibit a negative base or an exponent < 1, it still throws an error. Can anyone help? Thanks in advance.

@. H(x,p) = p[1] - (p[1]-p[2]) / ( 1. + (x/p[3])^p[4] )
Hfit = LsqFit.curve_fit(H,xdata,ydata,[1.,0.,0.5,1.],lower=[0.,0.,0.,1.])


DomainError with -...:
Exponentiation yielding a complex result requires a complex argument.
Replace x^y with (x+0im)^y, Complex(x)^y, or similar.

It works fine for me. Since you don’t give example data, I generated some:

fx(x) = 1.5 - 1.3 / (1. + (x/0.7)^1.3)
xdata = range(0,3,length=50)
ydata = fx.(xdata).*(1 .+0.1randn(50))

leads to:

Next, doing model fitting:

julia> @. H(x,p) = p[1] - (p[1]-p[2]) / ( 1. + (x/p[3])^p[4] )
julia> Hfit = LsqFit.curve_fit(H,xdata,ydata,[1.,0.,0.5,1.],lower=[0.,0.,0.,1.])
julia> par = coef(Hfit)
4-element Array{Float64,1}:

julia> plot(xdata,ydata,label="data")
julia> plot!(xdata,x-> par[1] - (par[1]-par[2])/(1+(x/par[3])^par[4]),label="fitted model",legend=:bottomright)

leads to:

Of course, if you have negative elements in xdata, you will have problems as x/p[3] will be negative, and raising this to a number that is not an even integer will produce a complex number.

Another problem is that you allow p[3] to have zero as lower bound, hence allows the fitting algorithm to divide by zero in x/p[3].

So, I’d check the minimal value in xdata, and change the lower value of p[3] to 1e-2 or something.

You do indicate that xdata contains concentrations, which should be positive at the outset. Maybe there are some errors in the measurements so that some of them are (slightly) negative??


There were indeed a few negative values in xdata. Thanks!