0
$\begingroup$

I was not able to use a self defined (using Module and For loops) piecewise function to fit data. It seems that the problem is that I have to define a pure function. I would like to learn how to define pure functions in the following example using Modules and For loops. Please help.

So let's consider a problem - we have some data, and a self defined piecewise function f[z] that goes exactly through all the data points. LinearModelFit fitting data with f[z] should return value parameter equal to 1.

Disclaimer: it will return a constant instead (basically will not understand what is the f[z] provided and will use a constant to fit the data).

However, in the second part of the following example I will define a function g[z] (which will be equal to f[z]) using Piecewise[] and it will work perfectly (LinearModeFit will return 1).

So, once again, I would like to write f[z] using Module and For loops so that it works in LinearModelFit the way g[z] does.

x = Table[x + Random[], {x, 1, 5}];
y = 2 # + Random[] & /@ x;
data = Transpose@{x, y};

Part 1: self defined function f[z]

fpiecewise[x_, xlist_, ylist_] := Module[{i = 1},
   For[i = 1, i < Length[xlist], i++, If[x <= xlist[[i]], Break[]]];
   Return[ylist[[i]]]
   ];
f[z_] := fpiecewise[z, x, y];

LinearModelFit[data, f[z], z]; 
ListPlot[{{x, % /@ x} // Transpose, data}, Joined -> True]

Part1

Part 2: Piecewise[] defined function g[z]

x1 = Join[{0.}, x];
g[z_] := Piecewise[
  Table[{y[[i]], x1[[i]] < z <= x1[[i + 1]]}, {i, 1, Length[x]}]]
LinearModelFit[data, g[z], z];
ListPlot[{{x, % /@ x} // Transpose, data}, Joined -> True]

Part2

$\endgroup$
2
  • 1
    $\begingroup$ Classic mistake fpiecewise[x_?NumberQ, ... $\endgroup$
    – swish
    Commented May 26, 2013 at 22:57
  • $\begingroup$ @swish, thank you for your help! However, I didn't get it. f[z] was returning expected numeric values when I had fpiecewise[x, ... (without ?NumberQ). I was able to Plot[] it as well. So, what was exactly the problem with using it in Fit[]? Could you, please, refer to a source that discusses this question in more details? $\endgroup$ Commented May 27, 2013 at 9:43

1 Answer 1

0
$\begingroup$

As swish pointed out:

fpiecewise[x_**?NumberQ**, xlist_, ylist_] := Module[{i = 1},
   For[i = 1, i < Length[xlist], i++, If[x <= xlist[[i]], Break[]]];   
   Return[ylist[[i]]]
];

f[z_] := fpiecewise[z, x, y];

LinearModelFit[data, f[z], z]; 

f[z] defined this way will do the job as successfully as g[z].

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.