code: def calc_free_energy(qs, prior, n_factors, likelihood=None):
      """Calculate variational free energy
      @TODO Primarily used in FPI algorithm, needs to be made general
      """
      free_energy = 0
      for factor in range(n_factors):
          # Neg-entropy of posterior marginal H(q[f])
          negH_qs = qs[factor].dot(
              np.log(qs[factor][:, np.newaxis] + 1e-16)
          )
          # Cross entropy of posterior marginal with prior marginal H(q[f],p[f])
          xH_qp = -qs[factor].dot(prior[factor][:, np.newaxis])
          free_energy += negH_qs + xH_qp
  
      if likelihood is not None:
          free_energy -= compute_accuracy(likelihood, qs)
      return free_energy
  
imports: import numpy
  from scipy import special
  from pymdp import utils
  from itertools import chain
label_desc: Use image node_id 17 for calling a global function with example usage: calc_free_energy(qs, prior, n_factors, likelihood) and returns: free_energy