Project: 043_Proxy_Denoising_for_Source-Free_Domain_Adaptation | Function: IID_loss (iclr)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Computes the mutual information (MI) loss for clustering. This loss measures and maximizes the mutual information between softmax predictions from different augmentations of the same input. The objective is I(z, z') = H(z) - H(z|z') where z and z' are predictions from different views.

**KEY TERMS:** {
  "x_out": "target predictions p_i",
  "x_tf_out": "denoised ViL predictions p'_i",
  "p_i_j": "joint distribution for mutual information",
  "loss": "negative mutual information -MI(p'_i, p_i)"
}

**CONTEXT CODE:** import sys

import torch


def IID_loss(x_out, x_tf_out, lamb=1.0, EPS=sys.float_info.epsilon):
    raise NotImplementedError("Function implementation has been masked for testing")

def compute_joint(x_out, x_tf_out):
  # produces variable that requires grad (since args require grad)

  bn, k = x_out.size()
  assert (x_tf_out.size(0) == bn and x_tf_out.size(1) == k)

  p_i_j = x_out.unsqueeze(2) * x_tf_out.unsqueeze(1)  # bn, k, k
  p_i_j = p_i_j.sum(dim=0)  # k, k
  p_i_j = (p_i_j + p_i_j.t()) / 2.  # symmetrise
  p_i_j = p_i_j / p_i_j.sum()  # normalise

  return p_i_j

Complete the function implementation replacing "raise NotImplementedError".