function r = randn(varargin)
%MATLAB Code Generation Library Function

%   Limitations:  
%   Does not support dispatching to a static RANDN method of a user-defined
%   class, i.e. randn(m,n,'myclass') will not dispatch to myclass.randn(m,n).

%   Copyright 2005-2016 The MathWorks, Inc.
%#codegen

coder.internal.prefer_const(varargin);
EXTRINSIC = eml_is_rand_extrinsic;
if nargin > 0 && coder.internal.isCharOrScalarString(varargin{1}) && isLegacyCommand(varargin{1})
    % Handle seed-related tasks.
    eml_invariant(nargin <= 2, ...
        'Coder:toolbox:randn_1', ...
        'IfNotConst','Fail');
    eml_invariant(nargin == 1 || nargout == 0, ...
        'Coder:toolbox:randn_2', ...
        'IfNotConst','Fail');
    eml_invariant(nargin == 1 || coder.internal.isBuiltInNumeric(varargin{2}), ...
        'Coder:toolbox:randn_3', ...
        'IfNotConst','Fail');
    eml_invariant(eml_is_const(varargin{1}), ...
        'Coder:toolbox:randn_4', ...
        'IfNotConst','Fail');
    % Return state information or set generator and state.
    if strcmp(varargin{1},'state')
        if nargin == 1
            if EXTRINSIC
                r = coder.nullcopy(coder.const(feval('randn', 'state')));
                r = feval('randn', varargin{:});
            else
                r = double(eml_randn('state'));
            end
        else
            if EXTRINSIC
                feval('randn', varargin{:});
            else
                
                arg2 = varargin{2};
                eml_invariant(eml_is_const(size(arg2)), ...
                    'Coder:toolbox:randn_5', ...
                    'IfNotConst','Fail');
                eml_invariant(isa(arg2,'double') && ...
                    (isscalar(arg2) || isequal(size(arg2),[2,1])), ...
                    'MATLAB:randn:invalidState', ...
                    'IfNotConst','Fail');
                eml_randn('method',eml_rand_str2id('shr3cong'));
                if isscalar(arg2)
                    eml_randn('state',eml_rand_shr3cong('seed_to_state',eml_randn('state'),arg2));
                else
                    eml_randn('state',eml_cast(floor(arg2),'uint32','floor','spill'));
                end
            end
        end
    elseif strcmp(varargin{1},'seed')
        if nargin == 1
            if EXTRINSIC
                r = 0;
                r = feval('randn', varargin{:});
            else
                state = eml_randn('state');
                [~,r] = eml_rand_mcg16807('state_to_seed',state(1));
            end
        else
            if EXTRINSIC
                feval('randn', varargin{:});
            else
                arg2 = varargin{2};
                eml_invariant(eml_is_const(size(arg2)), ...
                    'Coder:toolbox:randn_5', ...
                    'IfNotConst','Fail');
                eml_invariant(isa(arg2,'double') && isscalar(arg2), ...
                    'MATLAB:randn:invalidSeed', ...
                    'IfNotConst','Fail');
                eml_randn('method',eml_rand_str2id('mcg16807'));
                eml_randn('state',[eml_rand_mcg16807('seed_to_state',uint32(0),arg2);uint32(0)]);
            end
        end
    else
        eml_invariant(false, ...
            'Coder:toolbox:randn_8', ...
            'IfNotConst','Fail');
    end
    return
end

% Handle any 'like' syntax
if nargin >= 2 && coder.internal.isCharOrScalarString(varargin{end-1})
    eml_invariant(eml_is_const(varargin{end-1}), ...
                          'Coder:toolbox:RandLikeConst', ...
                          'IfNotConst', 'Fail');
    eml_invariant(strcmpi(varargin{end-1}, 'like'), ...
                          'MATLAB:randn:inputType', ...
                          'IfNotConst', 'Fail');
    egArg = varargin{end};
    if coder.internal.isBuiltInNumeric(egArg) || ~isobject(egArg)
        eml_invariant(coder.internal.isFloatClass(class(egArg)), ...
                              'MATLAB:randn:invalidPrototype', ...
                              'IfNotConst', 'Fail');
        eml_invariant(isreal(egArg), ...
                              'MATLAB:randn:complexOrSparsePrototype', ...
                              'IfNotConst', 'Fail');
        r = randn(varargin{1:end-2}, class(egArg));
    else
        r = randnLike(egArg, varargin{1:end-2});
    end
elseif EXTRINSIC
    r = coder.nullcopy(zeros(varargin{:}));
    if ~isempty(r)
        if (isa(r,'double'))
            coder.ceval('-jit','emlrtRandn',coder.wref(r(1)),coder.internal.indexInt(numel(r)));
        else %if (isa(r,'single'))
             % Batch process converting double values to singles in chunks of 128.  This
             % needs to be done since emlrtRandn requires a double buffer.  Do not
             % apply special rounding just do a straight cast to single.
            r = eml_rand_batch_call(r,'emlrtRandn',false);
        end
    end
else
    coder.inline('never');
    r = eml_randn('generate',varargin{:});
end
