code: def test_clipped_ppo_loss_discrete_batch_time():
      batch_size = 3
      time_steps = 4
      num_actions = 2
  
      # actions taken, of shape (batch_size, time_steps)
      actions = mx.nd.array(((0, 1, 0, 0), (1, 1, 0, 0), (0, 0, 0, 0)))
      # advantages from taking action, of shape (batch_size, time_steps)
      advantages = mx.nd.array(
          ((-2, 2, 1, 0), (-1, 1, 0, 1), (-1, 0, 1, 0))
      )
      # action probabilities, of shape (batch_size, num_actions)
      old_policy_probs = mx.nd.array(
          (
              ((0.8, 0.2), (0.5, 0.5), (0.5, 0.5), (0.5, 0.5)),
              ((0.5, 0.5), (0.5, 0.5), (0.5, 0.5), (0.5, 0.5)),
              ((0.5, 0.5), (0.5, 0.5), (0.5, 0.5), (0.5, 0.5)),
          )
      )
      new_policy_probs_worse = mx.nd.array(
          (
              ((0.9, 0.1), (0.5, 0.5), (0.5, 0.5), (0.5, 0.5)),
              ((0.5, 0.5), (0.5, 0.5), (0.5, 0.5), (0.5, 0.5)),
              ((0.5, 0.5), (0.5, 0.5), (0.5, 0.5), (0.5, 0.5)),
          )
      )
      new_policy_probs_better = mx.nd.array(
          (
              ((0.2, 0.8), (0.5, 0.5), (0.5, 0.5), (0.5, 0.5)),
              ((0.5, 0.5), (0.5, 0.5), (0.5, 0.5), (0.5, 0.5)),
              ((0.5, 0.5), (0.5, 0.5), (0.5, 0.5), (0.5, 0.5)),
          )
      )
  
      # check lower loss for policy with better probabilities:
      # i.e. higher probability on high advantage actions, low probability on low advantage actions.
      loss_fn = ClippedPPOLossDiscrete(
          num_actions=num_actions,
          clip_likelihood_ratio_using_epsilon=0.2,
      )
      loss_fn.initialize()
  
      clip_param_rescaler = mx.nd.array((1,))
  
      loss_worse = loss_fn(
          new_policy_probs_worse,
          actions,
          old_policy_probs,
          clip_param_rescaler,
          advantages,
      )
      loss_better = loss_fn(
          new_policy_probs_better,
          actions,
          old_policy_probs,
          clip_param_rescaler,
          advantages,
      )
  
      assert (
          len(loss_worse) == 6
      )  # (LOSS, REGULARIZATION, KL, ENTROPY, LIKELIHOOD_RATIO, CLIPPED_LIKELIHOOD_RATIO)
      loss_worse_val = loss_worse[0]
      assert loss_worse_val.ndim == 1
      assert loss_worse_val.shape[0] == 1
      assert (
          len(loss_better) == 6
      )  # (LOSS, REGULARIZATION, KL, ENTROPY, LIKELIHOOD_RATIO, CLIPPED_LIKELIHOOD_RATIO)
      loss_better_val = loss_better[0]
      assert loss_better_val.ndim == 1
      assert loss_better_val.shape[0] == 1
      assert loss_worse_val > loss_better_val
  
imports: import mxnet
  import numpy
  import os
  import pytest
  from scipy import stats
  import sys
  from rl_coach.architectures.head_parameters import PPOHeadParameters
  from rl_coach.architectures.mxnet_components.heads.ppo_head import CategoricalDist, MultivariateNormalDist, DiscretePPOHead, ClippedPPOLossDiscrete, ClippedPPOLossContinuous, PPOHead
  from rl_coach.agents.clipped_ppo_agent import ClippedPPOAlgorithmParameters, ClippedPPOAgentParameters
  from rl_coach.spaces import SpacesDefinition, DiscreteActionSpace
label_desc: Use image node_id 15 for calling a global function with example usage: test_clipped_ppo_loss_discrete_batch_time() without return types