function values = rsval(rs,x)
%RSVAL Evaluate rational spline.
%
%   RSVAL(RS,X)  returns the value at X of the rational spline 
%   whose rBform or rpform is in RS.
%
%   Specifically, this means that the d-vector valued rational spline in
%   RS is evaluated at X with the aid of SPVAL or PPUAL as if it were an 
%   ordinary (d+1)-vector valued spline, then each of the resulting values
%   is divided by its last entry (changed to 1 in case it is zero),
%   and then that last entry is omitted.
%
%   The output is a matrix of size [d*m,n] if the function in RS is
%   univariate and d-vector valued, and [m,n] == size(X) .
%
%   If the function in RS is m-variate with m>1 and d-vector valued, then
%
%                         [d,n],         if X is of size [m,n]
%   the output is of size [d,n1,...,nm], if d>1  and X is {X1,...,Xm} 
%                         [n1,...,nm],   if d==1 and X is {X1,...,Xm} 
%
%   See also FNVAL, SPVAL, PPVAL, RSMAK, RPMAK.

%   Carl de Boor 23 may 99
%   Copyright 1987-2000 by C. de Boor and The MathWorks, Inc.
%   $Revision: 1.4 $  $Date: 2000/04/25 14:14:05 $

if ~isstruct(rs)  error('The first argument must be a structure.'), end

% treat rs as a spline in B-form or ppform:

switch rs.form(2)
case 'B', temp = spval(fn2fm(rs,'B-'),x); 
case 'p', temp = ppual(fn2fm(rs,'pp'),x); 
otherwise
   error('The function is not a rational spline.')
end

% divide each resulting (d+1)-vector by its last entry (having changed any
% zero entry to 1), then return only the first d entries:

d = fnbrk(rs,'dim'); temp(d+1,find(temp(d+1,:)==0)) = 1;

sv = size(temp); 
if length(sv)<3 newsize = [d*sv(1)/(d+1),sv(2)];
else            newsize = [d,sv(2:end)];
end

temp = reshape(temp,d+1,prod(sv)/(d+1));
values = reshape(temp(1:d,:)./temp(repmat(d+1,d,1),:),newsize);
