class_docstr: Calculate the diffusion based on first-order differentiation of ``pred`` using central finite difference.
  For the original paper, please refer to
  VoxelMorph: A Learning Framework for Deformable Medical Image Registration,
  Guha Balakrishnan, Amy Zhao, Mert R. Sabuncu, John Guttag, Adrian V. Dalca
  IEEE TMI: Transactions on Medical Imaging. 2019. eprint arXiv:1809.05231.
  
  For more information,
  see https://github.com/Project-MONAI/tutorials/blob/main/modules/bending_energy_diffusion_loss_notes.ipynb.
  
  Adapted from:
      VoxelMorph (https://github.com/voxelmorph/voxelmorph)
class_docstr_tok: ["Calculate","the","diffusion","based","on","first-order","differentiation","of","``","pred","``","using","central","finite","difference",".","For","the","original","paper",",","please","refer","to","VoxelMorph",":","A","Learning","Framework","for","Deformable","Medical","Image","Registration",",","Guha","Balakrishnan",",","Amy","Zhao",",","Mert","R.","Sabuncu",",","John","Guttag",",","Adrian","V.","Dalca","IEEE","TMI",":","Transactions","on","Medical","Imaging",".","2019.","eprint","arXiv:1809.05231",".","For","more","information",",","see","https",":","\/\/github.com\/Project-MONAI\/tutorials\/blob\/main\/modules\/bending_energy_diffusion_loss_notes.ipynb",".","Adapted","from",":","VoxelMorph","(","https",":","\/\/github.com\/voxelmorph\/voxelmorph",")"]
docstr: Args:
      pred:
          Predicted dense displacement field (DDF) with shape BCH[WD],
          where C is the number of spatial dimensions.
          Note that diffusion loss can only be calculated
          when the sizes of the DDF along all spatial dimensions are greater than 2.
  
  Raises:
      ValueError: When ``self.reduction`` is not one of ["mean", "sum", "none"].
      ValueError: When ``pred`` is not 3-d, 4-d or 5-d.
      ValueError: When any spatial dimension of ``pred`` has size less than or equal to 2.
      ValueError: When the number of channels of ``pred`` does not match the number of spatial dimensions.
docstr_tok: ["Args",":","pred",":","Predicted","dense","displacement","field","(","DDF",")","with","shape","BCH","[","WD","]",",","where","C","is","the","number","of","spatial","dimensions",".","Note","that","diffusion","loss","can","only","be","calculated","when","the","sizes","of","the","DDF","along","all","spatial","dimensions","are","greater","than","2",".","Raises",":","ValueError",":","When","``","self.reduction","``","is","not","one","of","[","``","mean","''",",","``","sum","''",",","``","none","''","]",".","ValueError",":","When","``","pred","``","is","not","3-d",",","4-d","or","5-d.","ValueError",":","When","any","spatial","dimension","of","``","pred","``","has","size","less","than","or","equal","to","2",".","ValueError",":","When","the","number","of","channels","of","``","pred","``","does","not","match","the","number","of","spatial","dimensions","."]
code: def forward(self, pred: torch.Tensor) -> torch.Tensor:
      """
      Args:
          pred:
              Predicted dense displacement field (DDF) with shape BCH[WD],
              where C is the number of spatial dimensions.
              Note that diffusion loss can only be calculated
              when the sizes of the DDF along all spatial dimensions are greater than 2.
  
      Raises:
          ValueError: When ``self.reduction`` is not one of ["mean", "sum", "none"].
          ValueError: When ``pred`` is not 3-d, 4-d or 5-d.
          ValueError: When any spatial dimension of ``pred`` has size less than or equal to 2.
          ValueError: When the number of channels of ``pred`` does not match the number of spatial dimensions.
  
      """
      if pred.ndim not in [3, 4, 5]:
          raise ValueError(
              f"Expecting 3-d, 4-d or 5-d pred, instead got pred of shape {pred.shape}"
          )
      for i in range(pred.ndim - 2):
          if pred.shape[-i - 1] <= 2:
              raise ValueError(
                  f"All spatial dimensions must be > 2, got spatial dimensions {pred.shape[2:]}"
              )
      if pred.shape[1] != pred.ndim - 2:
          raise ValueError(
              f"Number of vector components, i.e. number of channels of the input DDF, {pred.shape[1]}, "
              f"does not match number of spatial dimensions, {pred.ndim - 2}"
          )
  
      # first order gradient
      first_order_gradient = [
          spatial_gradient(pred, dim) for dim in range(2, pred.ndim)
      ]
  
      # spatial dimensions in a shape suited for broadcasting below
      if self.normalize:
          spatial_dims = torch.tensor(pred.shape, device=pred.device)[
              2:
          ].reshape((1, -1) + (pred.ndim - 2) * (1,))
  
      diffusion = torch.tensor(0)
      for dim_1, g in enumerate(first_order_gradient):
          dim_1 += 2
          if self.normalize:
              # We divide the partial derivative for each vector component at each voxel by the spatial size
              # corresponding to that component relative to the spatial size of the vector component with respect
              # to which the partial derivative is taken.
              g *= pred.shape[dim_1] / spatial_dims
          diffusion = diffusion + g**2
  
      if self.reduction == LossReduction.MEAN.value:
          diffusion = torch.mean(
              diffusion
          )  # the batch and channel average
      elif self.reduction == LossReduction.SUM.value:
          diffusion = torch.sum(
              diffusion
          )  # sum over the batch and channel dims
      elif self.reduction != LossReduction.NONE.value:
          raise ValueError(
              f'Unsupported reduction: {self.reduction}, available options are ["mean", "sum", "none"].'
          )
  
      return diffusion
  
file_path: MONAI/monai/losses/deform.py
imports: from __future__ import annotations
  import torch
  from torch.nn.modules.loss import _Loss
  from monai.utils import LossReduction
label_desc: Use image node_id 2 for calling the DiffusionLoss obj's underlying member method code with example usage: obj.forward(pred) and returns: diffusion