简体   繁体   中英

MATLAB Piecewise function

I have to construct the following function in MATLAB and am having trouble.

Consider the function s(t) defined for t in [0,4) by

              { sin(pi*t/2)  , for t in [0,1)
       s(t) = { -(t-2)^3     , for t in [1,3)*
              { sin(pi*t/2)  , for t in [3,4)

(i) Generate a column vector s consisting of 512 uniform samples of this function over the interval [0,4). (This is best done by concatenating three vectors.)

I know it has to be something of the form.

N = 512;
s = sin(5*t/N).' ;

But I need s to be the piecewise function, can someone provide assistance with this?

If I understand correctly, you're trying to create 3 vectors which calculate the specific function outputs for all t , then take slices of each and concatenate them depending on the actual value of t . This is inefficient as you're initialising 3 times as many vectors as you actually want (memory), and also making 3 times as many calculations (CPU), most of which will just be thrown away. To top it off, it'll be a bit tricky to use concatenate if your t is ever not as you expect (ie monotonically increasing). It might be an unlikely situation, but better to be general.

Here are two alternatives, the first is imho the nice Matlab way, the second is the more conventional way (you might be more used to that if you're coming from C++ or something, I was for a long time).

function example()
    t = linspace(0,4,513); % generate your time-trajectory
    t = t(1:end-1); % exclude final value which is 4

    tic
    traj1 = myFunc(t);
    toc

    tic
    traj2 = classicStyle(t);
    toc
end

function trajectory = myFunc(t)
    trajectory = zeros(size(t)); % since you know the size of your output, generate it at the beginning. More efficient than dynamically growing this.

    % you could put an assert for t>0 and t<3, otherwise you could end up with 0s wherever t is outside your expected range

    % find the indices for each piecewise segment you care about
    idx1 = find(t<1); 
    idx2 = find(t>=1 & t<3);
    idx3 = find(t>=3 & t<4);

    % now calculate each entry apprioriately
    trajectory(idx1) = sin(pi.*t(idx1)./2);
    trajectory(idx2) = -(t(idx2)-2).^3;
    trajectory(idx3) = sin(pi.*t(idx3)./2);
end

function trajectory = classicStyle(t)
    trajectory = zeros(size(t));

    % conventional way: loop over each t, and differentiate with if-else
    % works, but a lot more code and ugly
    for i=1:numel(t)
        if t(i)<1
            trajectory(i) = sin(pi*t(i)/2);
        elseif t(i)>=1 & t(i)<3
            trajectory(i) = -(t(i)-2)^3;
        elseif t(i)>=3 & t(i)<4
            trajectory(i) = sin(pi*t(i)/2);
        else
            error('t is beyond bounds!')
        end
    end     
end

Note that when I tried it, the 'conventional way' is sometimes faster for the sampling size you're working on, although the first way ( myFunc ) is definitely faster as you scale up really a lot. In anycase I recommend the first approach, as it is much easier to read.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM