%#codegen
%#internal
function out = range_dsp_minimum(h, in1)
    eml_prefer_const(h);
    if h.RunningMinimum
        [rangeLow, rangeHigh] = range_running_dsp_minimum_impl(in1);
        out = [rangeLow, rangeHigh];
    else
        [rangeLow, rangeHigh] = range_dsp_minimum_impl(in1);
        out = [rangeLow, rangeHigh];
    end
end

function [rangeLow, rangeHigh] = range_running_dsp_minimum_impl(in1)
    persistent runMaxLow runMaxHigh
    if isempty(runMaxLow)
        % First call to the step.
        [rangeLow, rangeHigh] = range_dsp_minimum_impl(in1);        
        runMaxLow = rangeLow;
        runMaxHigh = rangeHigh;
    else
        % Subsequence calls to step
        [rangeLow, rangeHigh] = range_dsp_minimum_impl(in1);
        
        % The new high cannot be greater than previous max.
        rangeHigh = min(rangeHigh, runMaxHigh);
        
        % The new low is minimum of current and previous high
        rangeLow = min(rangeLow, runMaxLow);
        
        

        runMaxLow = rangeLow;
        runMaxHigh = rangeHigh;        
    end
end

function [rangeLow, rangeHigh] = range_dsp_minimum_impl(in1)
    coder.inline('always');
    % Return both minimum and minimum values.
    % This is needed for cases where dsp.minimum returns a vector.
    % See g944472    
    values = in1(:);
    if isreal(values)     
        rangeLow = min(values);
        rangeHigh = max(values);
    else
        % Take minimum and minimum of real and imaginary parts separately.
        % Otherwise constructs like sqrt, exp etc will be introduced.
        values_re = real(values);
        values_im = imag(values);
        rangeLow = min(min(values_re), min(values_im));
        rangeHigh = max(max(values_re), max(values_im));
    end
end

