2

Ignore the red fitted curve first. I'd like to get a curve to the blue datapoints. I know the first part (up to y~200 in this case) is linear, then a different curve (combination of two logarithmic curves but could also be approximated differently) and then it saturates at about 250 or 255. I tried it like this:

func = fittype('(x>=0 & x<=xTrans1).*(A*x+B)+(x>=xTrans1 & x<=xTrans2).*(C*x+D)+(x>=xTrans2).*E*255');
freg = fit(foundData(:,1), foundData(:,2), func);
plot(freg, foundData(:,1), foundData(:,2))

Okay obviously my fittype could be improved, but why is it actually THAT bad/wrong? I tried another simpler model:

func = fittype('(x>=0 & x<=xTrans1).*(A*x+B)+(x>=xTrans1).*(C*x+D)')
freg = fit(foundData(:,1), foundData(:,2), func);
plot(freg, foundData(:,1), foundData(:,2))

At least I'd expect there two be two linear functions, and what I get is:

Or is it only the plot which is wrong because the output of the fit is:

 General model:
 f_fit(x) = (x>=0 & x<=xTrans1).*(A*x+B)+(x>=xTrans1).*(C*x+D)
 Coefficients (with 95% confidence bounds):
   A =      0.6491
   B =      0.7317
   C =   0.0007511
   D =       143.5
   xTrans1 =       0.547

Which at least yields a good xTrans1 (but I can't see it in the plot)!


EDIT Thanks for pointing out the more clear way of programming the function to fit, I tried the following (three different linear functions with two transition points):

function y = singleRegression_ansatzfunktion(x,xtrans1,xtrans2,a,b,c,d,e,f)
y = zeros(size(x));

% 3 Geradengleichungen:
for i = 1:length(x)
    if x(i) < xtrans1
        y(i) = a + b.* x(i);
    elseif(x(i) < xtrans2)
        y(i) = c + d.* x(i);
    else
        y(i) = e + f.* x(i);
    end
end

Calling the fitter like that:

freg = fit(foundData(:,1), foundData(:,2), 'singleRegression_ansatzfunktion(x,xtrans1,xtrans2,a,b,c,d,e,f)');
plot(freg, foundData(:,1), foundData(:,2))

Resulting in:

 General model:
 f(x) = singleRegression_ansatzfunktion(x,xtrans1,xtrans2,a,b,c,d,e,f)
 Coefficients (with 95% confidence bounds):
   a =      0.7655
   b =      0.7952
   c =      0.1869
   d =      0.4898
   e =       159.2
   f =   0.0005512
   xtrans1 =      0.7094
   xtrans2 =      0.7547

!!!!Strange!!!!


EDIT2 When NOT letting MATLAB optimize the transition points but entering them myself like I shortly did in the cftool (should be the same like calling fit but was quicker to figure it out) via the custom equation:

(x>=0 & x<=2.9e4).*(A*x+B)+(x>2.9e4 & x<=1.3e5).*(B*x+D)+(x>1.3e5).*255

It worked pretty well. I don't know why MATLAB can't do this on his own but okay... There you go now as a result:

So at least I fixed it now but I still remain in doubt why MATLAB simply couldn't do this itself.

tim
  • 9,896
  • 20
  • 81
  • 137

1 Answers1

2

Have you tried the approach in the fittype documentation page ("Fit Curve Defined by a File" example) i.e. define your function to fit in a file to see if it makes a difference?

The other approach I can think of would be to split your data in two (or more) different datasets and do two separate fits for each chunk (but that assumes you know a priori where the transition point(s) is/are or can work it/them out before fitting).

am304
  • 13,758
  • 2
  • 22
  • 40
  • Thanks for the hint, I'm going to try it. But I'm still wondering why it gives me that problem as I thought MATLAB could easily handle that type of fit and as one can see from the plot the least square error can't be the minimum. But yeah, splitting would work but I'd love to have an approaching-function in ONE line instead of manually splitting the data :( – tim Nov 29 '13 at 14:17
  • 1
    I'm suggesting breaking up the data as a step towards understanding (and fixing) what's going on rather than a long-term solution. – am304 Nov 29 '13 at 14:20
  • Okay I think I really have to break it up as the function in a file doesn't get me to a solution either (look at my edit above in a sec) - or is there something wrong with it? – tim Nov 29 '13 at 14:32
  • 1
    I can't see anything wrong with it. The only thing I'm wondering about is `x` and `y` are of vastly different scales. It might be worth trying to scale the data before fitting and make sure sure `x` and `y` are of about the same order of magnitude. It might give better results. – am304 Nov 29 '13 at 14:52
  • I finally figured it out via setting the transitions myself, see my edit above :-) – tim Nov 29 '13 at 14:53
  • And me again: I also found out that it works when at least providing some sort of start-value for certain parameters... It seems that MATLAB then can better find the "perfect" values... – tim Nov 29 '13 at 15:20
  • I'm guessing under the hood it uses some sort of optimization and certainly providing good starting values will help, especially if you have a fair number of parameters, as you do. Anyway, glad you found a solution. Can you accept the answer if it helped? – am304 Nov 29 '13 at 15:43