cosmo isequaln

function tf=cosmo_isequaln(x,y)
% compares two input for equality with NaNs considered being equal
%
% tf=cosmo_isequaln(x,y)
%
% Inputs:
%   x                   first input
%   y                   second input, to be compared with first input
%
% Output:
%   tf                  true if x and y are equal, with NaNs considered
%                       to be equal; false otherwise
%
% Examples:
%    cosmo_isequaln(2,2)
%    > true
%    cosmo_isequaln(2,3)
%    > false
%    % using the builtin isequal, NaNs are considered not equal
%    isequal(NaN,NaN)
%    > false
%    % using cosmo_isequaln, NaNs are considered to be equal to each other
%    cosmo_isequaln(NaN,NaN)
%    > true

% Notes:
%   - in earlier versions of Matlab, isequaln did not exist;
%     isequalwithequalnans was used instead. However isequaln will be
%     deprecated in GNU Octave 4.2. This function is there included for
%     compatibility with both old versions of Matlab and future versions of
%     GNU Octave
%
% See also: isequaln, isequalwithequalnans

    comparison_func=get_comparison_func();
    tf=comparison_func(x,y);


function func=get_comparison_func()
    persistent cached_comparison_func

    if isempty(cached_comparison_func)
        cached_comparison_func=find_comparison_func_helper();
    end

    func=cached_comparison_func;


function func=find_comparison_func_helper()
    candidates_str={'isequaln','isequalwithequalnans'};

    has_func=@(x)~isempty(which(x,'builtin'));
    idx=find(cellfun(has_func,candidates_str),1,'first');
    if ~isempty(idx)
        func=str2func(candidates_str{idx});
        return
    end

    error('No comparison function found from candidates: %s',...
                cosmo_strjoin(candidates_str,', '));