code: def feature_embedding(
      input_feats: ndarray, out_feat_len: int
  ) -> ndarray:
      """Embed features. This code was partially adapted from
      https://github.com/GXYM/DRRG licensed under the MIT license.
  
      Args:
          input_feats (ndarray): The input features of shape (N, d), where N is
              the number of nodes in graph, d is the input feature vector length.
          out_feat_len (int): The length of output feature vector.
  
      Returns:
          ndarray: The embedded features.
      """
      assert input_feats.ndim == 2
      assert isinstance(out_feat_len, int)
      assert out_feat_len >= input_feats.shape[1]
  
      num_nodes = input_feats.shape[0]
      feat_dim = input_feats.shape[1]
      feat_repeat_times = out_feat_len // feat_dim
      residue_dim = out_feat_len % feat_dim
  
      if residue_dim > 0:
          embed_wave = np.array(
              [
                  np.power(1000, 2.0 * (j // 2) / feat_repeat_times + 1)
                  for j in range(feat_repeat_times + 1)
              ]
          ).reshape((feat_repeat_times + 1, 1, 1))
          repeat_feats = np.repeat(
              np.expand_dims(input_feats, axis=0),
              feat_repeat_times,
              axis=0,
          )
          residue_feats = np.hstack(
              [
                  input_feats[:, 0:residue_dim],
                  np.zeros((num_nodes, feat_dim - residue_dim)),
              ]
          )
          residue_feats = np.expand_dims(residue_feats, axis=0)
          repeat_feats = np.concatenate(
              [repeat_feats, residue_feats], axis=0
          )
          embedded_feats = repeat_feats / embed_wave
          embedded_feats[:, 0::2] = np.sin(embedded_feats[:, 0::2])
          embedded_feats[:, 1::2] = np.cos(embedded_feats[:, 1::2])
          embedded_feats = np.transpose(
              embedded_feats, (1, 0, 2)
          ).reshape((num_nodes, -1))[:, 0:out_feat_len]
      else:
          embed_wave = np.array(
              [
                  np.power(1000, 2.0 * (j // 2) / feat_repeat_times)
                  for j in range(feat_repeat_times)
              ]
          ).reshape((feat_repeat_times, 1, 1))
          repeat_feats = np.repeat(
              np.expand_dims(input_feats, axis=0),
              feat_repeat_times,
              axis=0,
          )
          embedded_feats = repeat_feats / embed_wave
          embedded_feats[:, 0::2] = np.sin(embedded_feats[:, 0::2])
          embedded_feats[:, 1::2] = np.cos(embedded_feats[:, 1::2])
          embedded_feats = (
              np.transpose(embedded_feats, (1, 0, 2))
              .reshape((num_nodes, -1))
              .astype(np.float32)
          )
  
      return embedded_feats
  
imports: from typing import Dict, List, Optional, Sequence, Tuple, Union
  import cv2
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from mmcv.ops import RoIAlignRotated
  from mmengine.model import BaseModule
  from numpy import ndarray
  from torch import Tensor
  from torch.nn import init
  from mmocr.models.textdet.heads import BaseTextDetHead
  from mmocr.registry import MODELS
  from mmocr.structures import TextDetDataSample
  from mmocr.utils import fill_hole
label_desc: Use image node_id 3 for calling a global function with example usage: feature_embedding(input_feats, out_feat_len) and returns: embedded_feats