function X = internal_embed(X,weights) 
%INTERNAL_EMBED Extract embedding from matrix WEIGHTS using indices in X
%
%    Y = INTERNAL_EMBED(X,WEIGHTS,EMBEDSIZE) returns the embedding vectors
%    in WEIGHTS corresponding to the numeric indices in X. WEIGHTS is a
%    matrix of size EMBEDSIZE-by-(VocabularySize+1). Each element of X that
%    is not in the set 1:VocabularySize is replaced by the index
%    VocabularySize+1. Y has shape EMBEDSIZE-by-size(X).

%   Copyright 2020 The MathWorks, Inc.

% Get vocabulary dimension (includes OoV word)
[~, 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;

if isa(X, "gpuArray") && ~isa(weights, "gpuArray")
    weights = gpuArray(weights);
end

try
    X = reshape(weights(:,X), [size(weights,1) size(X)]); 
catch e
    if e.identifier == "MATLAB:badsubscript"
        error(message('deep:dlarray:EmbedNonValidIndices'))
    else
        throw(e)
    end
end
