function y = bssbasisfun( x, m )
%BSSBASISFUN Vectorized evaluation of the mth order normalized, uniform B-Spline.

%
% INPUTS:
%
%    x:
%        A scalar value, column vector, or matrix of values for which
%        the value of the B-spline of order m is desired.
%
%     m:
%        The bspline order. m >= 1.
%
% OUTPUTS:
%
%    y: 
%        Output values of the bspline evaluated at x. The shape will be
%        the same as the input shape.
%

%
% Copyright 2014-2018 Biometrics Northwest LLC
%

%
% Modified: 2018-08-21
% Author : Kevin R. Gehringer
%
%    Modified the comments and input/output descriptions to a standardized
%    format.
%
%    Added a copyright notice.
%
%    Removed unnecessary variable assignments that were used only once by
%    substituting in the appropriate formula.
%
%    Replaced two calls to repmat with one call to bsxfun. This
%    dramatically improved performance.
%
%    Changed the output varialbe name to y.
%
% Modified: 2016-03-12
% Author : Kevin R. Gehringer
%
%    Several enhancements were made to improve the performance:
%
%    1) Removed redundant range checking of input values.
%    2) Replaced outer products with vectors of ones used to replicate data
%       with calls to REPMAT. Since REPMAT is now a built-in function it is
%       significantly faster than using the outer product to do replication.
%    3) Removed unnecessary preallocation of the output values.
%
% Created: 2014-11-25
% Author : Kevin R. Gehringer
%

if ( m < 1 )
   error('The B-spline order must be at least 1.\n');
end

nicv = ~iscolumn(x);

if (nicv)
   d = size(x);
   x = x(:);
end

xm     = bsxfun(@minus,x,0:m-1);
bmofx  = double ( (xm >= 0.0) & (xm < 1.0) );

for j = m:-1:2
   mmjp1 = m-j+2;
   mmj   = m-j+1;
   for i = 1:j-1
      bmofx(:,i) = (xm(:,i).*bmofx(:,i)+(mmjp1-xm(:,i)).*bmofx(:,i+1))/mmj;
   end
end

if(nicv)
   y = reshape(bmofx(:,1),d);
else
   y = bmofx(:,1);
end
