function tf = isequaln(x, y)
%ISEQUALN True if arrays are numerically equal, treating NaNs as equal.
%   TF = ISEQUALN(A,B)
%   
%   A and B are equal if the numeric data they represent is equal, treating
%   NaNs as equal, and if they have the same dimension labels or neither
%   has dimension labels.
%
%   See also ISEQUALN, DLARRAY, DLARRAY/NAN.

%   Copyright 2019-2022 The MathWorks, Inc.

% Note: isequal(dlarray(x'), dlarray(x)') returns true, although they are
% not represented the same way internally.
% Also, whether an array is recording does not matter here.

if isa(x, 'dlarray') && isa(y, 'dlarray')
    if isequal(dims(x), dims(y)) && isequal(size(x), size(y))
        xdata = gatherData(x.FormattedData);
        ydata = gatherData(y.FormattedData);
        xperm = x.ViewToDataMap;
        yperm = y.ViewToDataMap;
        if (isempty(xperm) && isempty(yperm)) || isequal(xperm, yperm)
            tf = isequaln(xdata, ydata);
        else
            [xperm, yperm] = matchPermLengths(xperm, yperm);
            xyperm(xperm) = yperm;
            tf = isequaln(xdata, permute(ydata, xyperm));
        end
    else
        tf = false;
    end
else % Only one of x and y is a dlarray
    if isa(y, 'dlarray')
        tmp = x;
        x = y;
        y = tmp;
    end
    
    if ~isempty(dims(x))
        tf = false;
    else
        tf = isequaln(extractdata(x), y);
    end
end
end


function [permx, permy] = matchPermLengths(permx, permy)
% If permx and permy have different lengths, extend the shorter one.
lx = length(permx);
ly = length(permy);
if lx > ly
    permy(ly+1:lx) = ly+1:lx;
elseif lx < ly
    permx(lx+1:ly) = lx+1:ly;
end
end
