I have data points (x, y) that I need to fit an exponential function to,
y = A + B * exp(C * x),
but I can neither use the Curve Fitting Toolbox nor the Optimization Toolbox.
User rayryeng was good enough to help me with working code:
x = [0 0.0036 0.0071 0.0107 0.0143 0.0178 0.0214 0.0250 0.0285 0.0321 0.0357 0.0392 0.0428 0.0464 0.0464];
y = [1.3985 1.3310 1.2741 1.2175 1.1694 1.1213 1.0804 1.0395 1.0043 0.9691 0.9385 0.9080 0.8809 0.7856 0.7856];
M = [ones(numel(x),1), x(:)]; %// Ensure x is a column vector
lny = log(y(:)); %// Ensure y is a column vector and take ln
X = M\lny; %// Solve for parameters
A = exp(X(1)); %// Solve for A
b = X(2); %// Get b
xval = linspace(min(x), max(x));
yval = A*exp(b*xval);
plot(x,y,'r.',xval,yval,'b');
However, this code only fits the equation without offset
y = A * exp(B * x).
How can I extend this code to fit the three-parameter equation?
In another attempt, I managed to fit the function using fminsearch
:
function [xval, yval] = curve_fitting_exponential_1_optimized(x,y,xval)
start_point = rand(1, 3);
model = @expfun;
est = fminsearch(model, start_point);
function [sse, FittedCurve] = expfun(params)
A = params(1);
B = params(2);
C = params(3);
FittedCurve = A + B .* exp(-C * x);
ErrorVector = FittedCurve - y;
sse = sum(ErrorVector .^ 2);
end
yval = est(1)+est(2) * exp(-est(3) * xval);
end
The problem here is that the result depends on the starting point which is randomly chosen, so I don't get a stable solution. But since I need the function for automatization, I need something stable. How can I get a stable solution?
fminsearch
as I described here. – TroyHaskinM\(lny-ln(min(y)))
and use those as starting values for fminsearch. That should give a good first estimate in any case, but you need to determine if this is actually faster than justs starting from a sane, (but not random!) initial guess. – rubenvb