function pp = mkpp(breaks,coefs,d)
%MATLAB Code Generation Library Function

%   Limitations:
%   1. For code generation the output structure contains only two fields,
%      breaks and coefs. Consequently, this structure cannot be used
%      directly by PPVAL in MATLAB, nor can MATLAB PP forms be used
%      directly by PPVAL in MATLAB Coder.  However, UNMKPP in MATLAB Coder
%      supports standard PP forms constructed in MATLAB.
%
%   2. If D is not supplied, coefs must be 2-D and have a fixed number of
%      columns. The number of columns will always be the order in this
%      case.
%
%   3. To define a piecewise constant polynomial, COEFS must be a column
%      vector or DIM must have at least two elements.
%
%   4. If D is supplied and D == 1, it is important that D be a
%      constant 1. If D is a variable that might assume a value other than
%      1, the output size when PPVAL is given a non-scalar input may have a
%      different shape than MATLAB.
%
%   4. When D is supplied, it must have fixed length, and one of the
%      following is required.
%
%      Let m = length(d) and npieces = length(breaks) - 1.
%      a) size(coefs,j) = d(j), j = 1,2,...,m
%         size(coefs,m+1) = npieces
%         size(coefs,m+2) = order (must be a fixed-length dimension).
%      b) (Same requirements as when d is not supplied)
%         size(coefs,1) = prod(d)*npieces
%         size(coefs,2) = order (must be a fixed-length dimension).

%   Copyright 1984-2014 The MathWorks, Inc.
%#codegen

coder.inline('always');
eml_invariant(nargin >= 2,'MATLAB:minrhs');
ndc = eml_ndims(coefs);
nb = numel(breaks);
eml_invariant(nb >= 2,'MATLAB:chckxy:NotEnoughPts')
npieces = nb - 1;
if nargin < 3
    d = 1;
    dlen = 1;
else
    coder.internal.prefer_const(d);
    eml_invariant(isnumeric(d) && ...
        eml_is_const(size(d)) && isrow(d) && ...
        allNonnegativeInteger(d), ...
        'Coder:toolbox:InvalidD');
    dlen = length(d);
end
dlenp2 = coder.const(dlen + 2);
if ndc == 2
    % If the order is 1, then either
    % (a) size(coefs,1) == prod(d)*npieces && size(coefs,2) == 1
    % (b) size(coefs,1) == d               && size(coefs,2) == npieces
    % We have to support (a) because it is the output form for UNMKPP.
    % Don't support (b) because we may not be able to determine the
    % order in that case.
    coder.internal.errorIf(dlen == 1 && npieces > 1 && ...
        size(coefs,1) == d(1) && size(coefs,2) == npieces, ...
        'Coder:toolbox:OrderOneRequiresColumnVector');
    order = size(coefs,2);
else
    for j = coder.unroll(1:dlen)
        eml_invariant(size(coefs,j) == d(j), ...
            'Coder:toolbox:SizeCoefsAndDNotConsistent');
    end
    order = size(coefs,dlenp2);
end
eml_invariant(eml_is_const(order), ...
    'Coder:toolbox:OrderDimMustBeFixed');
newsize = [d,npieces,order];
eml_invariant(prod(newsize) == numel(coefs), ...
     'Coder:toolbox:MKPPSizeMismatch');
pp = makepp(breaks,reshape(coefs,newsize),dlenp2);

%--------------------------------------------------------------------------

function p = allNonnegativeInteger(d)
p = true;
for k = 1:numel(d)
    if ~(d(k) >= 0 && d(k) == floor(d(k)) && ...
            d(k) <= intmax(coder.internal.indexIntClass))
        p = false;
        break
    end
end

%--------------------------------------------------------------------------
