parameters: (self, values)
docstring: Gives the (sub/super)gradient of the atom w.r.t. each argument.
  
          Matrix expressions are vectorized, so the gradient is a matrix.
  
          Args:
              values: A list of numeric values for the arguments.
  
          Returns:
              A list of SciPy CSC sparse matrices or None.
docstring_summary: Gives the (sub/super)gradient of the atom w.r.t. each argument.
docstring_tokens: Gives the ( sub / super ) gradient of the atom w . r . t . each argument .
function: def _grad(self, values) -> List[Optional[csc_matrix]]:
          """Gives the (sub/super)gradient of the atom w.r.t. each argument.
  
          Matrix expressions are vectorized, so the gradient is a matrix.
  
          Args:
              values: A list of numeric values for the arguments.
  
          Returns:
              A list of SciPy CSC sparse matrices or None.
          """
          if np.min(values[0]) <= 0 or np.min(values[1]) <= 0:
              # Non-differentiable.
              return [None, None]
          else:
              div = values[0]/values[1]
              grad_vals = [np.log(div), 1 - div]
              grad_list = []
              for idx in range(len(values)):
                  rows = self.args[idx].size
                  cols = self.size
                  grad_list += [kl_div.elemwise_grad_to_diag(grad_vals[idx],
                                                             rows, cols)]
              return grad_list
function_tokens: def _grad ( self , values ) -> List [ Optional [ csc_matrix ] ] : if np . min ( values [ 0 ] ) <= 0 or np . min ( values [ 1 ] ) <= 0 : # Non-differentiable. return [ None , None ] else : div = values [ 0 ] / values [ 1 ] grad_vals = [ np . log ( div ) , 1 - div ] grad_list = [ ] for idx in range ( len ( values ) ) : rows = self . args [ idx ] . size cols = self . size grad_list += [ kl_div . elemwise_grad_to_diag ( grad_vals [ idx ] , rows , cols ) ] return grad_list