class_docstr: - Separate: we use different kernel for each output latent
  - Independent: Latents are uncorrelated a priori.
class_docstr_tok: ["-","Separate",":","we","use","different","kernel","for","each","output","latent","-","Independent",":","Latents","are","uncorrelated","a","priori","."]
code: def K(
      self,
      X: TensorType,
      X2: Optional[TensorType] = None,
      full_output_cov: bool = True,
  ) -> tf.Tensor:
      rank = tf.rank(X) - 1
      if X2 is None:
          if full_output_cov:
              Kxxs = cs(
                  tf.stack([k.K(X, X2) for k in self.kernels], axis=-1),
                  "[batch..., N, N, P]",
              )
              perm = tf.concat(
                  [
                      tf.range(rank),
                      [rank + 1, rank, rank + 2],
                  ],
                  0,
              )
              return cs(
                  tf.transpose(tf.linalg.diag(Kxxs), perm),
                  "[batch..., N, P, N, P]",
              )
          else:
              return cs(
                  tf.stack([k.K(X, X2) for k in self.kernels], axis=0),
                  "[P, batch..., N, N]",
              )
      else:
          rank2 = tf.rank(X2) - 1
          if full_output_cov:
              Kxxs = cs(
                  tf.stack([k.K(X, X2) for k in self.kernels], axis=-1),
                  "[batch..., N, batch2..., N2, P]",
              )
              perm = tf.concat(
                  [
                      tf.range(rank),
                      [rank + rank2],
                      rank + tf.range(rank2),
                      [rank + rank2 + 1],
                  ],
                  0,
              )
              return cs(
                  tf.transpose(tf.linalg.diag(Kxxs), perm),
                  "[batch..., N, P, batch2..., N2, P]",
              )
          else:
              return cs(
                  tf.stack([k.K(X, X2) for k in self.kernels], axis=0),
                  "[P, batch..., N, batch2..., N2]",
              )
  
imports: import abc
  from typing import Optional, Sequence, Tuple
  import tensorflow
  from check_shapes import check_shape
  from check_shapes import check_shapes, inherit_check_shapes
  from ...base import Parameter, TensorType
  from ..base import Combination, Kernel
label_desc: Use image node_id 4 for calling the SeparateIndependent obj's underlying member method code with example usage: obj.K(X, X2, full_output_cov) and returns: cs, cs, cs, cs