code: def calc_pB_info_gain(pB, qs_pi, qs_prev, policy):
      """
      Compute expected Dirichlet information gain about parameters ``pB`` under a given policy
  
      Parameters
      ----------
      pB: ``numpy.ndarray`` of dtype object
          Dirichlet parameters over transition model (same shape as ``B``)
      qs_pi: ``list`` of ``numpy.ndarray`` of dtype object
          Predictive posterior beliefs over hidden states expected under the policy, where ``qs_pi[t]`` stores the beliefs about
          hidden states expected under the policy at time ``t``
      qs_prev: ``numpy.ndarray`` of dtype object
          Posterior over hidden states at beginning of trajectory (before receiving observations)
      policy: 2D ``numpy.ndarray``
          Array that stores actions entailed by a policy over time. Shape is ``(num_timesteps, num_factors)`` where ``num_timesteps`` is the temporal
          depth of the policy and ``num_factors`` is the number of control factors.
  
      Returns
      -------
      infogain_pB: float
          Surprise (about dirichlet parameters) expected under the policy in question
      """
  
      n_steps = len(qs_pi)
  
      num_factors = len(pB)
      wB = utils.obj_array(num_factors)
      for factor, pB_f in enumerate(pB):
          wB[factor] = spm_wnorm(pB_f)
  
      pB_infogain = 0
  
      for t in range(n_steps):
          # the 'past posterior' used for the information gain about pB here is the posterior
          # over expected states at the timestep previous to the one under consideration
          # if we're on the first timestep, we just use the latest posterior in the
          # entire action-perception cycle as the previous posterior
          if t == 0:
              previous_qs = qs_prev
          # otherwise, we use the expected states for the timestep previous to the timestep under consideration
          else:
              previous_qs = qs_pi[t - 1]
  
          # get the list of action-indices for the current timestep
          policy_t = policy[t, :]
          for factor, a_i in enumerate(policy_t):
              wB_factor_t = wB[factor][:, :, int(a_i)] * (
                  pB[factor][:, :, int(a_i)] > 0
              ).astype("float")
              pB_infogain -= qs_pi[t][factor].dot(
                  wB_factor_t.dot(previous_qs[factor])
              )
  
      return pB_infogain
  
imports: import itertools
  import numpy
  from pymdp.maths import softmax, softmax_obj_arr, spm_dot, spm_wnorm, spm_MDP_G, spm_log_single, spm_log_obj_array
  from pymdp import utils
  import copy
label_desc: Use image node_id 8 for calling a global function with example usage: calc_pB_info_gain(pB, qs_pi, qs_prev, policy) and returns: pB_infogain