code: def average_states_over_policies(qs_pi, q_pi):
      """
      This function computes a expected posterior over hidden states with respect to the posterior over policies,
      also known as the 'Bayesian model average of states with respect to policies'.
  
      Parameters
      ----------
      qs_pi: ``numpy.ndarray`` of dtype object
          Posterior beliefs over hidden states for each policy. Nesting structure is policies, factors,
          where e.g. ``qs_pi[p][f]`` stores the marginal belief about factor ``f`` under policy ``p``.
      q_pi: ``numpy.ndarray`` of dtype object
          Posterior beliefs about policies where ``len(q_pi) = num_policies``
  
      Returns
      ---------
      qs_bma: ``numpy.ndarray`` of dtype object
          Marginal posterior over hidden states for the current timepoint,
          averaged across policies according to their posterior probability given by ``q_pi``
      """
  
      num_factors = len(
          qs_pi[0]
      )  # get the number of hidden state factors using the shape of the first-policy-conditioned posterior
      num_states = [
          qs_f.shape[0] for qs_f in qs_pi[0]
      ]  # get the dimensionalities of each hidden state factor
  
      qs_bma = utils.obj_array(num_factors)
      for f in range(num_factors):
          qs_bma[f] = np.zeros(num_states[f])
  
      for p_idx, policy_weight in enumerate(q_pi):
          for f in range(num_factors):
              qs_bma[f] += qs_pi[p_idx][f] * policy_weight
  
      return qs_bma
  
file_path: pymdp/pymdp/inference.py
imports: import numpy
  from pymdp import utils
  from pymdp.maths import get_joint_likelihood_seq
  from pymdp.algos import run_vanilla_fpi, run_mmp, _run_mmp_testing
label_desc: Use image node_id 3 for calling a global function with example usage: average_states_over_policies(qs_pi, q_pi) and returns: qs_bma