Fit different (but connected) equations to connected intervals, with ~arbitrary function on each interval
Show older comments
I have some data, with several different intervals (3 or 4 divisions), where I would like to fit a (connected) curve that follows the appropriate model in each interval. The outer models are connecting expontential decay functions, with decay lengths dependent on x, and the inner model is a simple line, with a tanh function connecting the line with the exponential decay functions. To avoid too much complication, I will reduce my question to its essence.
In a simple example, imagine I have data points that are two straight lines, with a knot in the middle. Taking the matlab example and modifying it slightly, lets say this is my function to use in the fit:
function y = profile_fit(x, slope1, slope2, amplitude, knot_location)
y = zeros(size(x));
for i = 1:length(x)
if x(i) < knot_location
y(i) = amplitude + slope1.* x(i);
else
y(i) = (amplitude+ slope1.*knot_location) + slope_2.* (x(i)-knot_location);
end
end
end
The knot location and amplitude is unknown, and the function follows slope1 with amplitude before the knot, and then slope2 after the knot, with the corresponding amplitude and position modified to connect the line appropriately with the first line.
In this case, I don't know the knot location or amplitude, but can (probably) provide slope1 and slope2. To do the fit, I'd like to be able to run it such that:
% Define (arbitrary):
slope1 = 5;
slope2 = -2;
% Define fit based on function:
profile_ft = fittype('profile_fit2(x, slope1, slope2, amplitude, knot_location)','problem',{'slope1','slope2'})
% Create some data with noise
noise = randn(100,1);
x_data = linspace(0,100,100);
x_data = x_data + noise;
knot = 52;
ampl = 11;
y_data = profile_fit(x_data, slope1, slope2, ampl, knot)
% This is the fit that I would like:
the_fit = fit(x_data, y_data, profile_ft, 'problem',{'slope1','slope2'},'StartPoint',{10, 50});
% parameters to return: amplitude (should be 11), knot_location (should be 52)
works as intended.
However, instead I get a complicated error, likely because the knot_location is not nicely defined this way.
Error using fittype/testCustomModelEvaluation (line 12)
Expression profile_fit(x, slope1, slope2, amplitude, knot_location) is not a valid MATLAB expression, has non-scalar
coefficients, or cannot be evaluated:
Error in fittype expression ==> profile_fit(x, slope1, slope2, amplitude, knot_location)
??? Undefined function 'profile_fit' for input arguments of type 'double'.
Error in fittype>iCreateFittype (line 373)
testCustomModelEvaluation( obj );
Error in fittype (line 330)
obj = iCreateFittype( obj, varargin{:} );
Error in profile_fit (line 6)
profile_ft = fittype('profile_fit(x, slope1, slope2, amplitude, knot_location)','problem',{'slope1','slope2'})
Caused by:
Error using fittype/evaluate (line 106)
Error in fittype expression ==> profile_fit(x, slope1, slope2, amplitude, knot_location)
??? Undefined function 'profile_fit2' for input arguments of type 'double'.
Aside from trying to use 'fit', I've come across the possibilty of using 'fminsearch' for simultaneous fitting of two functions with a knot in the middle, but this example knew where the knot is... Whereas for me, I'd like to determine that from the data.
Can anyone please help? Thank you.
Accepted Answer
More Answers (0)
Categories
Find more on Get Started with Curve Fitting Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!