function n = nnz(x)
%nnz Codegen overload of fi's nnz method
%  n = nnz(X) returns the number of non-zero elements
%  in X.
%
%  X is a scalar, vector, matrix, or ND-array.
%    
%  For MATLAB Built-In types, fi floating-point, and Scaled-Double inputs, N is returned as double.
%  For fixed-point fi objects, it is returned as a uint32 in the case that X has fewer than 2^32 elements.
%  Otherwise, it is a uint64.

    
% Copyright 2019 The MathWorks, Inc.
    
%#codegen

    
    coder.extrinsic('fixed.internal.type.zeroRepresentableInType')
    coder.extrinsic('fixed.internal.type.isEquivalentToBuiltin');
    coder.extrinsic('fixed.internal.type.isScaledDouble');

    validateattributes(x, {'numeric','embedded.fi','logical'},{},'nnz');
    
    if coder.const(fixed.internal.type.isEquivalentToBuiltin(cast([],'like',x)))
        n = nnz(fixed.internal.math.castFiToMATLAB(x));
        return
    elseif coder.const(fixed.internal.type.isScaledDouble(cast([],'like',x)))
        n = nnz(double(x));
        return
    end
    
    sizeX = coder.const(numel(x));
    if coder.const(...
        fixed.internal.type.zeroRepresentableInType(...
            cast([],'like',x))) % if
        n = coder.const(getZeroIndex(sizeX));
        for ii = 1:sizeX
            n(:) = n + cast(x(ii) ~= 0,'like',n);
        end
    else
        n = cast(sizeX,'like',getZeroIndex(sizeX));
    end % end if
end

function zeroIdx = getZeroIndex(sizeX)
%getZeroIndex Get a zero index in a type large enough to count all elements of x
    if(sizeX < 2^32)
        zeroIdx = uint32(0); 
    else
        zeroIdx = uint64(0);
    end
end

