How to create a piecewise built-in function in MATLAB?

I have a function in MATLAB that takes another function as an argument. I would like to somehow define a piecewise inline function that can be passed. Is this possible in MATLAB?

Edit: the function I would like to introduce is:

f(x) = { 1.0, 0.0 <= x <= 0.5, -1.0, 0.5 < x <= 1.0 where 0.0 <= x <= 1.0 
+7
function matlab inline piecewise
source share
4 answers

You really defined a piecewise function with three break points, i.e. in [0, 0.5, 1]. However, you did not define the value of the function outside the gaps. (By the way, I used the term “break” here because we really define a simple spline shape, a piecewise continuous spline. Maybe I used the term “knot”, another common word in the world of splines.)

If you absolutely know that you will never evaluate a function outside [0,1], then there are no problems. Then just define the piecewise function with ONE break point, at x = 0.5. An easy way to define a piecewise constant function like yours is to use a logical operator. Thus, the test (x> 0.5) returns a constant, either 0 or 1. Using scaling and translating this result, it is easy to create a function that does what you want.

 constfun = @(x) (x > 0.5)*2 - 1; 

An inline function performs a similar function, but inline functions are VERY slow compared to an anonymous function. I highly recommend using an anonymous form. As a test, try the following:

 infun = inline('(x > 0.5)*2 - 1','x'); x = 0:.001:1; tic,y = constfun(x);toc Elapsed time is 0.002192 seconds. tic,y = infun(x);toc Elapsed time is 0.136311 seconds. 

Yes, the built-in function took much longer to execute than the anonymous form.

The problem with the simple piecewise constant form that I used here is hard to expand when you have more breakpoints. For example, suppose you wanted to define a function that took three different values ​​depending on what time interval the point hit? Although this can also be done with the creative use of tests by carefully moving and scaling them, it can become unpleasant. For example, how can you define a piecewise function that returns

 -1 when x < 0, 2 when 0 <= x < 1, 1 when 1 <= x 

One solution is to use the Heaviside function. So, first define the basic Heaviside function.

 H = @(x) (x >= 0); 

Our piecewise function is now derived from H (x).

 P = @(x) -1 + H(x)*3 + H(x-1)*(-1); 

See that there are three parts to P (x). The first term is what happens for x below the first breakpoint. Then add the part that acts above zero. Finally, the third part is added to another offset above x == 1. This is easily drawn.

 ezplot(P,[-3,3]) 

From this beginning, more complex splines are easily generated. Se that I called this construction a spline again. In fact, this is where we could lead. In fact, this is where it happens. A spline is a piecewise function carefully linked together in a list of nodes or break points. Splines, in particular, often have predetermined orders of continuity, for example, a cubic spline will differentiate twice (C2) through gaps. There are also piecewise cubic functions that are only C1 functions. My point in all of this is that I have described a simple starting point for creating any piecewise function. This works well for polynomial splines, although a bit of math may be required to select the coefficients of these functions.

Another way to create this function is explicit piecewise polynomial. In MATLAB we have a little known function mkpp. Try it...

 pp = mkpp([0 .5 1],[1;-1]); 

If you were to use spline tools, fnplt will build it right for you. Assuming you do not have this TB, do the following:

 ppfun = @(x) ppval(pp,x); ezplot(ppfun,[0 1]) 

Looking back at the mkpp call, it's pretty simple. The first argument is a list of break points of the curve (like the ROW vector). The second argument is the COLUMN vector with piecewise constant values ​​that the curve will take in these two defined gaps between the gaps.

A few years ago I published another option, piecewise wedge . It can be downloaded using MATLAB Central file sharing. This is a function that allows the user to specify a piecewise function only as a list of breakpoints, as well as functional fragments between these breaks. Thus, for a function with one gap at x = 0.5, we would do this:

 fun = @(x) piecewise_eval(x,0.5,{1,-1}); 

See that the third argument provides the value used in each segment, although these parts are not necessarily purely constant functions. If you want the function to return, perhaps, NaN outside the interval of interest, this is also easy to accomplish.

 fun = @(x) piecewise_eval(x,[0 0.5 1],{NaN,1,-1,NaN}); 

My point on this rather long excursion is to understand what a piecewise function is, and several ways to create it in MATLAB.

+12
source share

Unfortunately, MATLAB does not have a ternary operator to simplify this, but by expanding the gnovice approach a bit, you could create an anonymous function:

 fh = @(x) ( 2 .* ( x <= 0.5 ) - 1 ) 

In general, anonymous functions are more powerful than built-in function objects, and allow you to create closures, etc.

+5
source share

If you really want to make an inline function (as opposed to an anonymous function ), then the following is probably the easiest way

 f = inline('2.*(x <= 0.5)-1'); 

However, as indicated in other answers, anonymous functions are more commonly used and more efficient:

 f = @(x) (2.*(x <= 0.5)-1); 
+4
source share

I just had to solve this problem, and I think the easiest way is to use anonymous functions. Say you have a piecewise function:

 when x<0 : x^2 + 3x when 0<=x<=4: e^x when x>4 : log(x) 

First, I would define logical masks for each piece area:

 PIECE1 = @(x) x<0 PIECE2 = @(x) x>=0 & x<=4 PIECE3 = @(x) x>4 

Then I would put them all together:

 f = @(x) PIECE1(x).*(x.^2+3*x) + PIECE2(x).*exp(x) + PIECE3(x).*log(x) x = -10:.1:10 figure; plot(x,f(x)) 
+1
source share

All Articles