I don’t see anything obviously wrong with your code, but I’m not familiar with the CurveFit package, so i can’t tell if you’re using it incorrectly.
However, I was able to implement your problem pretty easily using Optim.jl
, which is a general-purpose optimization tool in Julia. Optim isn’t specifically meant for curve fitting, but it’s easy to make it work. Here’s my code:
x = linspace(-8, -4, 9) # sample x-values
y = [0, 0, 0.05, 0.2, 0.5, 0.8, 0.95, 1, 1] # sample y-values
# Define a helper function for the dose response
dose_response(x, p) = p[1] + ((p[2] - p[1]) / (1 + 10^((p[3] - x) * p[4])))
# Create an anonymous function called `cost` which
# does the following:
# * given parameter values p
# * for each sample in zip(x, y):
# * compute the expected dose response of x given p
# * take the squared absolute value of the error between
# that expected response and the measured response y
# * sum those squared errors to compute the total cost
#
# Optim.jl will try to find the values of p that minimize
# that cost.
cost = let samples = zip(x, y)
function (p)
sum(samples) do sample
x, y = sample
abs2(y - dose_response(x, p))
end
end
end
using Optim
# Construct a wrapper around our cost function. This wrapper
# knows how to compute its own derivatives with respect to the
# elements of p using automatic differentiation.
f = OnceDifferentiable(cost, zeros(4), autodiff=:forward)
# Create a totally random initial guess for p:
p0 = rand(4)
# Optimize the parameters p starting at that random guess
# using the LBFGS algorithm:
result = Optim.optimize(f, p0, LBFGS())
# Extract the optimal parameters from the result:
pstar = Optim.minimizer(result)
# Plot the result
plt = plot(x, y, marker=:dot, line=nothing)
xbase = collect(linspace(minimum(x), maximum(x), 100)) # x-values for fitted curve
plot!(plt, xbase, dose_response.(xbase, (pstar,)))
plt
Using the above code, I can reliably find what look (to my untrained eye) to be the correct parameters. Moreover, it works even if I start with a random p0,
and the optimization takes less than 10 milliseconds on my laptop.
So, given that this is definitely a solvable problem, I would venture that something is going wrong in CurveFit or in the way you’re using it. It’s hard to say more about that without any knowledge of the package, though.
Hope this helps!