Generating piecewise in r2016a
7 views (last 30 days)
Show older comments
Bryan Parthum
on 19 Feb 2017
Commented: Walter Roberson
on 28 May 2017
Hello!
Using r2016a with symbolic math toolbox, but perhaps it is lacking 'piecewise'? Hoping to work with the following function, but have failed with various approaches. Thank you in advance for your suggestions.
Function:
(3*x^2)/100 + 30 if x<22.3607
x^2/100 + 40 if 22.3607<=x<=109.5445
(3*x^2)/400 + 70 if x>109.5445
Option 1) SMT would probably allow:
syms y x
y(x) = piecewise([x<22.3607, (3*x^2)/100 + 30], [22.3607<=x<=109.5445, x^2/100 + 40], [x>109.5445, (3*x^2)/400 + 70)]);
Result:
>> Undefined function or variable 'piecewise'.
Option 2) Create function in .m file:
function y = y(x)
if x<=22.3607;
y = (3*x^2)/100 + 30;
else if 22.3607<x<=109.5445;
y = x^2/100 + 40;
else if 109.5445<x;
y = (3*x^2)/400 + 70;
end
end
end
Result:
>> y_piecewise
Not enough input arguments.
Error in y_piecewise (line 3)
if x<=22.3607;
Option 3) Use heavyside:
y = ['(heaviside(x)-heaviside(x-22.3607))*((3*x^2)/100 + 30) + ' ...
'(heaviside(x-22.3607)-heaviside(x-109.5445))*(x^2/100 + 40) + ' ...
'(heaviside(x-109.5445)-heaviside(x-800))*((3*x^2)/400 + 70)'];
yinv = finverse(y,x)
Result (trying to compute inverse):
>>yinv = 10.0*(x - 40.0)^(1/2)
I would like to be able to input a value for x into this piecewise equation and receive a value for y. I would ideally like to do this for the inverse of the above piecewise function as well. In addition, I would like to compute the diff() and int(), so I believe a symbolic function would be best suited for this. Thoughts? Thank you!!
- Bryan
0 Comments
Accepted Answer
Star Strider
on 19 Feb 2017
This works:
y = @(x) ((3*x.^2)/100 + 30) .* (x<22.3607) + (x.^2/100 + 40) .* ((22.3607<=x) & (x<=109.5445)) + ((3*x.^2)/400 + 70) .* (x>109.5445);
t = linspace(0, 150, 500);
figure(1)
plot(t, y(t))
grid
xlabel('t')
ylabel('y(t)')
title('Original Fincton')
yi = linspace(min(y(t)), max(y(t)), 20); % Interpolate Inverse
ti = interp1(y(t),t, yi, 'linear');
figure(2)
plot(y(t), t) % Plot Inverse
hold on
plot(yi, ti, 'pg', 'MarkerFaceColor','g') % Inverse Interpolated Values
hold off
grid
xlabel('y(t)')
ylabel('t')
title('Inverse Function')
It takes advantage of logical indexing and then just adding pieces of the vector to create a continuous line.
The inverse works with the interp1 function.
0 Comments
More Answers (2)
Walter Roberson
on 19 Feb 2017
Edited: Walter Roberson
on 19 Feb 2017
There is no MATLAB interface to piecewise before R2016b. It is possible to use evalin(symengine) to construct a piecewise object at the mupad level, but you cannot create a function of it.
f = evalin(symengine,'piecewise([x<5,x^2],[x>=5,-x])')
You can subs() into f or you can int(f, x)
Constructing the piecewise by way of a program at the MATLAB level requires some non-obvious steps. It would take me a bit of searching to find where I posted the required helper functions...
Found it.
You would need the helper function that constructs lists, and you would need feval(symengine, 'piecewise',LIST,LIST,...)
whete LIST was constructed by the helper function.
1 Comment
See Also
Categories
Find more on Assumptions 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!