docs: def iteration(self, node_status=True):
          """
          Execute a single model iteration
  
          :return: Iteration_id, Incremental node status (dictionary node->status)
          """
          # One iteration changes the opinion of all agents using the following procedure:
          # - first all agents communicate with institutional information I using a deffuant like rule
          # - then random pairs of agents are selected to interact  (N pairs)
          # - interaction depends on state of agents but also internal cognitive structure
  
          self.clean_initial_status(None)
  
          actual_status = {node: nstatus for node, nstatus in future.utils.iteritems(self.status)}
  
          if self.actual_iteration == 0:
              self.actual_iteration += 1
              delta, node_count, status_delta = self.status_delta(self.status)
              if node_status:
                  return {"iteration": 0, "status": self.status.copy(),
                          "node_count": node_count.copy(), "status_delta": status_delta.copy()}
              else:
                  return {"iteration": 0, "status": {},
                          "node_count": node_count.copy(), "status_delta": status_delta.copy()}
  
          # first interact with I
          I = self.params['model']['I']
          for node in self.graph.nodes():
              T = self.params['nodes']['cognitive'][node][2]
              R = self.params['nodes']['cognitive'][node][0]
              actual_status[node] = actual_status[node] + T * (I - actual_status[node])
              if R == 1:
                  actual_status[node] = 0.5 * (1 + actual_status[node])
              if R == -1:
                  actual_status[node] *= 0.5
  
          # then interact with peers
          for i in range(0, self.graph.number_of_nodes()):
              # select a random node
              n1 = list(self.graph.nodes)[np.random.randint(0, self.graph.number_of_nodes())]
  
              # select all of the nodes neighbours (no digraph possible)
              neighbours = list(self.graph.neighbors(n1))
              if len(neighbours) == 0:
                  continue
  
              # select second node - a random neighbour
              n2 = neighbours[np.random.randint(0, len(neighbours))]
  
              # update status of n1 and n2
              p1 = pow(actual_status[n1], 1.0 / self.params['nodes']['cognitive'][n1][1])
              p2 = pow(actual_status[n2], 1.0 / self.params['nodes']['cognitive'][n2][1])
  
              oldn1 = self.status[n1]
              if np.random.random_sample() < p2:  # if node 2 talks, node 1 gets changed
                  T1 = self.params['nodes']['cognitive'][n1][2]
                  R1 = self.params['nodes']['cognitive'][n1][0]
                  actual_status[n1] += (1 - T1) * (actual_status[n2] - actual_status[n1])
                  if R1 == 1:
                      actual_status[n1] = 0.5 * (1 + actual_status[n1])
                  if R1 == -1:
                      actual_status[n1] *= 0.5
              if np.random.random_sample() < p1:  # if node 1 talks, node 2 gets changed
                  T2 = self.params['nodes']['cognitive'][n2][2]
                  R2 = self.params['nodes']['cognitive'][n2][0]
                  actual_status[n2] += (1 - T2) * (oldn1 - actual_status[n2])
                  if R2 == 1:
                      actual_status[n2] = 0.5 * (1 + actual_status[n2])
                  if R2 == -1:
                      actual_status[n2] *= 0.5
  
          delta, node_count, status_delta = self.status_delta(actual_status)
          self.status = actual_status
          self.actual_iteration += 1
  
          if node_status:
              return {"iteration": self.actual_iteration - 1, "status": delta.copy(),
                      "node_count": node_count.copy(), "status_delta": status_delta.copy()}
          else:
              return {"iteration": self.actual_iteration - 1, "status": {},
                      "node_count": node_count.copy(), "status_delta": status_delta.copy()}