function [y, delta] = polyval(p,x,S)
%POLYVAL Polynomial evaluation.
%	If p is a vector of length d+1 whose elements are the coefficients
%	of a polynomial, then y = POLYVAL(p,x) is the value of the
%	polynomial evaluated at x.
%	    y = p(1)*x^d + p(2)*x^(d-1) + ... + p(d)*x + p(d+1)
%	If X is a matrix or vector, the polynomial is evaluated at all
%	points in X.
%
%	[y,delta] = POLYVAL(p,x,S) uses the optional output generated by
%	POLYFIT to generate error estimates, y +/- delta.
%	If the errors in the data input to POLYFIT are independent normal
%	with constant variance, y +/- delta contains at least 50% of the
%	predictions.
%
%	See POLYVALM for evaluation in a matrix sense.

%	Polynomial evaluation p(x) using Horner's method

%	J.N. Little 4-26-86
%	Revised 3-9-88 JNL, 5-5-93 BAJ
%	Copyright (c) 1984-94 by The MathWorks, Inc.

[m,n] = size(x);
nc = max(size(p));

if ((m+n) == 2) & (nargin < 3)
    % Make it scream for scalar x.  Polynomial evaluation can be
    % implemented as a recursive digital filter.
    y = filter(1,[1 -x],p);
    y = y(nc);
    return
end

% Do general case where X is an array
y = zeros(m,n);
for i=1:nc
    y = x .* y + p(i);
end

if nargin > 2 & nargout > 1
    x = x(:);
    [ms,ns] = size(S);
    if (ms ~= ns+2) | (nc ~= ns)
        error('S matrix must be n+2-by-n where n = length(p)')
    end
    R = S(1:nc,1:nc);
    df = S(nc+1,1);
    normr = S(nc+2,1);

    % Construct Vandermonde matrix.
    V(:,nc) = ones(length(x),1);
    for j = nc-1:-1:1
        V(:,j) = x.*V(:,j+1);
    end
    E = V/R;
    if nc == 1
        e = sqrt(1+(E.*E));
    else
        e = sqrt(1+sum((E.*E)')');
    end
    if df == 0
        disp('Warning: zero degrees of freedom implies infinite error bounds.')
        delta = Inf*e;
    else
        delta = normr/sqrt(df)*e;
    end
    delta = reshape(delta,m,n);
end
