class_docstr: Implements methods for applying unconditional and conditional regularization.
docstr: Implement unconditional regularization φ(x) ⊥⊥ A_i
  
  :param classifs: feature representations output from classifier layer (gφ(x))
  :param attribute_labels: attribute labels loaded with the dataset for attribute A_i
  :param num_envs: number of environments/domains
  :param E_eq_A: Binary flag indicating whether attribute (A_i) coinicides with environment (E) definition
docstr_tok: ["Implement","unconditional","regularization","\u03c6","(","x",")","\u22a5\u22a5","A_i",":","param","classifs",":","feature","representations","output","from","classifier","layer","(","g\u03c6","(","x",")",")",":","param","attribute_labels",":","attribute","labels","loaded","with","the","dataset","for","attribute","A_i",":","param","num_envs",":","number","of","environments\/domains",":","param","E_eq_A",":","Binary","flag","indicating","whether","attribute","(","A_i",")","coinicides","with","environment","(","E",")","definition"]
code: def unconditional_reg(
      self, classifs, attribute_labels, num_envs, E_eq_A=False
  ):
      """
      Implement unconditional regularization φ(x) ⊥⊥ A_i
  
      :param classifs: feature representations output from classifier layer (gφ(x))
      :param attribute_labels: attribute labels loaded with the dataset for attribute A_i
      :param num_envs: number of environments/domains
      :param E_eq_A: Binary flag indicating whether attribute (A_i) coinicides with environment (E) definition
  
      """
  
      penalty = 0
  
      if E_eq_A:  # Environment (E) and attribute (A) coincide
          if (
              self.E_conditioned is False
          ):  # there is no correlation between E and X_c
              for i in range(num_envs):
                  for j in range(i + 1, num_envs):
                      penalty += self.mmd(classifs[i], classifs[j])
  
      else:
          if self.E_conditioned:
              for i in range(num_envs):
                  unique_attr_labels = torch.unique(attribute_labels[i])
                  unique_attr_label_indices = []
                  for label in unique_attr_labels:
                      label_ind = [
                          ind
                          for ind, j in enumerate(attribute_labels[i])
                          if j == label
                      ]
                      unique_attr_label_indices.append(label_ind)
  
                  nulabels = unique_attr_labels.shape[0]
                  for aidx in range(nulabels):
                      for bidx in range(aidx + 1, nulabels):
                          penalty += self.mmd(
                              classifs[i][
                                  unique_attr_label_indices[aidx]
                              ],
                              classifs[i][
                                  unique_attr_label_indices[bidx]
                              ],
                          )
  
          else:  # this currently assumes we have a disjoint set of attributes (Aind) across environments i.e., environment is defined by multiple closely related values of the attribute
              overall_nmb_indices, nmb_id = [], []
              for i in range(num_envs):
                  unique_attrs = torch.unique(attribute_labels[i])
                  unique_attr_indices = []
                  for attr in unique_attrs:
                      attr_ind = [
                          ind
                          for ind, j in enumerate(attribute_labels[i])
                          if j == attr
                      ]
                      unique_attr_indices.append(attr_ind)
                      overall_nmb_indices.append(attr_ind)
                      nmb_id.append(i)
  
              nuattr = len(overall_nmb_indices)
              for aidx in range(nuattr):
                  for bidx in range(aidx + 1, nuattr):
                      a_nmb_id = nmb_id[aidx]
                      b_nmb_id = nmb_id[bidx]
                      penalty += self.mmd(
                          classifs[a_nmb_id][overall_nmb_indices[aidx]],
                          classifs[b_nmb_id][overall_nmb_indices[bidx]],
                      )
  
      return penalty
  
file_path: dowhy/dowhy/causal_prediction/algorithms/regularization.py
imports: import numpy
  import torch
  from torch import nn
  from torch.nn import functional
  from dowhy.causal_prediction.algorithms.utils import mmd_compute
label_desc: Use image node_id 3 for calling the Regularizer obj's underlying member method code with example usage: obj.unconditional_reg(classifs, attribute_labels, num_envs, E_eq_A) and returns: penalty