code: def calc_expected_utility(qo_pi, C):
      """
      Computes the expected utility of a policy, using the observation distribution expected under that policy and a prior preference vector.
  
      Parameters
      ----------
      qo_pi: ``list`` of ``numpy.ndarray`` of dtype object
          Predictive posterior beliefs over observations expected under the policy, where ``qo_pi[t]`` stores the beliefs about
          observations expected under the policy at time ``t``
      C: ``numpy.ndarray`` of dtype object
         Prior over observations or 'prior preferences', storing the "value" of each outcome in terms of relative log probabilities.
         This is softmaxed to form a proper probability distribution before being used to compute the expected utility.
  
      Returns
      -------
      expected_util: float
          Utility (reward) expected under the policy in question
      """
      n_steps = len(qo_pi)
  
      # initialise expected utility
      expected_util = 0
  
      # loop over time points and modalities
      num_modalities = len(C)
  
      # reformat C to be tiled across timesteps, if it's not already
      modalities_to_tile = [
          modality_i
          for modality_i in range(num_modalities)
          if C[modality_i].ndim == 1
      ]
  
      # make a deepcopy of C where it has been tiled across timesteps
      C_tiled = copy.deepcopy(C)
      for modality in modalities_to_tile:
          C_tiled[modality] = np.tile(
              C[modality][:, None], (1, n_steps)
          )
  
      C_prob = softmax_obj_arr(
          C_tiled
      )  # convert relative log probabilities into proper probability distribution
  
      for t in range(n_steps):
          for modality in range(num_modalities):
              lnC = spm_log_single(C_prob[modality][:, t])
              expected_util += qo_pi[t][modality].dot(lnC)
  
      return expected_util
  
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 5 for calling a global function with example usage: calc_expected_utility(qo_pi, C) and returns: expected_util