Reputation: 9909
Given the following curve
I'd like to determine the index of the x-data point where the curve begins to increase in earnest (in this example that would be around x=15).
While I understand derivatives can be used for determining inflection points, note that the data is noisy and I'm unsure that approach would allow me to clearly identify the "true inflection point" (x=15 in this case).
I'm wondering if a simpler approach would be feasible such as
Do you have any suggestions on how to accomplish this?
Sample data from above curve
index SQMean
_____ ____________
'0' '139.428574'
'1' '133.298706'
'2' '135.961044'
'3' '143.688309'
'4' '133.298706'
'5' '133.181824'
'6' '134.896103'
'7' '146.415588'
'8' '142.324677'
'9' '128.168839'
'10' '146.116882'
'11' '146.766235'
'12' '134.675323'
'13' '138.610382'
'14' '140.558441'
'15' '128.662338'
'16' '138.480515'
'17' '153.610382'
'18' '156.207794'
'19' '183.428574'
'20' '220.324677'
'21' '224.324677'
'22' '230.415588'
'23' '226.766235'
'24' '223.935059'
'25' '229.922073'
'26' '234.389618'
'27' '235.493500'
'28' '225.727280'
'29' '241.623383'
'30' '225.805191'
'31' '240.896103'
'32' '224.090912'
'33' '230.467529'
'34' '248.285721'
'35' '233.779221'
'36' '225.532471'
'37' '247.337662'
'38' '233.000000'
'39' '241.740265'
'40' '235.688309'
'41' '238.662338'
'42' '236.636368'
'43' '236.025970'
'44' '234.818176'
'45' '240.974030'
'46' '251.350647'
'47' '241.857147'
'48' '242.623383'
'49' '245.714279'
'50' '250.701294'
'51' '229.415588'
'52' '236.909088'
'53' '243.779221'
'54' '244.532471'
'55' '241.493500'
'56' '245.480515'
'57' '244.324677'
'58' '244.025970'
'59' '231.987015'
'60' '238.740265'
'61' '239.532471'
'62' '232.363632'
'63' '242.454544'
'64' '243.831161'
'65' '229.688309'
'66' '239.493500'
'67' '247.324677'
'68' '245.324677'
'69' '244.662338'
'70' '238.610382'
'71' '243.324677'
'72' '234.584412'
'73' '235.181824'
'74' '228.974030'
'75' '228.246750'
'76' '230.519485'
'77' '231.441559'
'78' '236.324677'
'79' '229.935059'
'80' '238.701294'
'81' '236.441559'
'82' '244.350647'
'83' '233.714279'
'84' '243.753250'
Upvotes: 2
Views: 3262
Reputation: 8477
If this is a one-off estimate, one thing you can do is to use the curve fitting tool from the Curve Fitting Toolbox. Here is an example where I fitted a piecewise linear function to your data:
(click on image for full size)
The function has the form
a * (x < b) + c * (x > d) + ((x - b) / (d - b) * (c - a) + a) * (x >= b) * (x <= d)
which says: there is a constant part for x < b
with value a
, another constant part for x > d
with value c
, and a linear ramp connecting them.
It is hard to fit such a function, and will only work well if you provide decent starting estimates (see small window in screenshot). It is therefore not a way to automate the process, but just to obtain improved estimates.
In this case, from a starting estimate of b = 15
the fit provides an improved estimate b = 16.58
with a 95%-CI of [15.96, 17.2]
, which indicates that indices 0 through 16 belong to the initial constant part.
The curve fitting tool can also generate code from your GUI specifications. In this case the result is:
[xData, yData] = prepareCurveData( index, SQMean );
% Set up fittype and options.
ft = fittype( 'a * (x < b) + c * (x > d) + ((x - b) / (d - b) * (c - a) + a) * (x >= b) * (x <= d)', 'independent', 'x', 'dependent', 'y' );
opts = fitoptions( ft );
opts.Display = 'Off';
opts.Lower = [-Inf -Inf -Inf -Inf];
opts.StartPoint = [140 15 230 20];
opts.Upper = [Inf Inf Inf Inf];
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
% Plot fit with data.
figure( 'Name', 'untitled fit 1' );
h = plot( fitresult, xData, yData );
legend( h, 'SQMean vs. index', 'untitled fit 1', 'Location', 'NorthEast' );
% Label axes
xlabel( 'index' );
ylabel( 'SQMean' );
grid on
Upvotes: 1