class_docstr: Utility class for calculating gradients.
class_docstr_tok: ["Utility","class","for","calculating","gradients","."]
docstr: Reverse broadcast from shape(grad_op_tree) to shape(x)
  
  Arguments:
      grad_op_tree (OpTreeNode or Tensor): The OpTreeNode to broadcast.
      x (OpTreeNode or Tensor): Provides the dimension to be broadcasted to.
      be: (Backend): The backend to be used.
  
  Returns:
      OpTreeNode or Tensor: The broadcasted result.
docstr_tok: ["Reverse","broadcast","from","shape","(","grad_op_tree",")","to","shape","(","x",")","Arguments",":","grad_op_tree","(","OpTreeNode","or","Tensor",")",":","The","OpTreeNode","to","broadcast",".","x","(","OpTreeNode","or","Tensor",")",":","Provides","the","dimension","to","be","broadcasted","to",".","be",":","(","Backend",")",":","The","backend","to","be","used",".","Returns",":","OpTreeNode","or","Tensor",":","The","broadcasted","result","."]
code: def _unbroadcast(grad_op_tree, x, be):
      """
      Reverse broadcast from shape(grad_op_tree) to shape(x)
  
      Arguments:
          grad_op_tree (OpTreeNode or Tensor): The OpTreeNode to broadcast.
          x (OpTreeNode or Tensor): Provides the dimension to be broadcasted to.
          be: (Backend): The backend to be used.
  
      Returns:
          OpTreeNode or Tensor: The broadcasted result.
      """
  
      if (not grad_op_tree) or (not x):
          return grad_op_tree
      if type(x) in _scalar_types:
          return 0.0
      in_shape = x.shape
      out_shape = grad_op_tree.shape
  
      if in_shape == out_shape:
          return grad_op_tree
      elif len(in_shape) == 2 and len(out_shape) == 2:
          # broadcasts
          if in_shape == (1, 1):
              # [1 * 1] -> [m * n]
              return be.sum(grad_op_tree)
          elif in_shape[0] == out_shape[0] and in_shape[1] == 1:
              # [m * 1] -> [m * n]
              return be.sum(grad_op_tree, axis=1)
          elif in_shape[0] == 1 and in_shape[1] == out_shape[1]:
              # [1 * n] -> [m * n]
              return be.sum(grad_op_tree, axis=0)
          # reductions
          elif (out_shape[0] == in_shape[0] and out_shape[1] == 1) or (
              out_shape[0] == 1 and out_shape[1] == in_shape[1]
          ):
              # TODO cleaner way to broadcast
              return 0 * x + grad_op_tree
          else:
              return NotImplemented
      else:
          return NotImplemented
  
imports: from __future__ import division
  from builtins import object, zip
  from neon.backends.backend import OpTreeNode, Tensor
  import numpy
  from functools import wraps
label_desc: Use image node_id 2 for calling the GradUtil obj's underlying member method code with example usage: obj._unbroadcast(grad_op_tree, x, be) and returns: grad_op_tree, int, grad_op_tree, NotImplemented, be, be, be, unknown, NotImplemented