function [dX, dW] = internal_embedBackward(dZ,X,weights)
%INTERNAL_EMBEDBACKWARD Back propagate the loss function derivative

%   Copyright 2020 The MathWorks, Inc.

dX = zeros(size(X), 'like', X);  

if nargout > 1
    % Get vocabulary dimension
    [wordEmbedSize, numWordsAndOOV] = size(weights);
    
    % Accounts for out-of-vocabulary words. "words" not present in the
    % vocabulary of 1-to-NumWords correspond to the OOV-th column of
    % weights. NaNs are mapped to numWordsAndOOV.
    X(isnan(X)) = numWordsAndOOV;
    X(X == 0 | X > numWordsAndOOV) = numWordsAndOOV;
        
    dW = zeros([wordEmbedSize, numWordsAndOOV], 'like', weights);
    X = cast(X, 'like', dW);
    dZ = cast(dZ, 'like', dW);
    [I, J] = ndgrid(1:size(dZ,1), X(:));
    cumul = accumarray([I(:), J(:)], dZ(:));
    dW(:,1:size(cumul,2)) = cumul;
end

end