function y=pieces(x,varargin)
% PIECES evaluates a function given by different expressions
% on several intervals. For example, suppose that we want 
% to either evaluate or plot the function f(x) that is 
% 2-x below -1, x.^2 on -1 to 1/2, and 2*x above 1/2, To
% find values of f on a row vector x=-2:0.05:3, we would 
% use this command.
%
% y=pieces(x,'2-x',-inf,-1,'x.^2',-1,1/2,'2*x',1/2,inf);
%
% Any number of functions may be used. The pattern for 
% additional ones is 
%
%     'expression',a,b 
% 
% Here, a,b are the lower and upper endpoints of the 
% interval. 
% 
% To obtain a plot of the function, simply omit the 
% output; the command below automatically generates 
% a plot.
%
% pieces(x,'2-x',-inf,-1,'x.^2',-1,1/2,'2*x',1/2,inf);
%
% 
% Professor Francis J. Narcowich 
% Department of Mathematics
% Texas A&M University
% College station, TX 77843-3368
%
% Last modified on April 14, 2001.

% Check for the correct number of inputs.
n=size(varargin,2);
if (ceil(n/3)>n/3),
    error('Incorrect number of inputs.')
end

% Initial arrays.
m=n/3; w=[]; y=[]; z=[]; bpts=[]; vals=[]; 

% This loop calculates the values from each piece.
for k=1:m,
    f=vectorize(fcnchk(varargin{3*k-2}));
    a=varargin{3*k-1};
    b=varargin{3*k};
        u=x(find((a<=x)&(x<b)));
    y=[y,feval(f,u).*ones(size(u))];
    if a~=-inf,
        A=feval(f,a);
        bpts=[bpts,a];
        vals=[vals,A];
        w=[w,NaN,A];
        z=[z,a,a];
    end
    w=[w,feval(f,u).*ones(size(u))];
    z=[z,u];
    if  b~=inf,
        B=feval(f,b);
        bpts=[bpts,b];
        vals=[vals,B];
        w=[w,B,NaN];
        z=[z,b,b];
    end
end
if b==x(end),
    y=[y,B];
end
if nargout==0,
plot(z,w,bpts,vals,'o')
end
