code: def evaluate_spherical_harmonics(
      degree_l: TensorLike,
      order_m: TensorLike,
      theta: TensorLike,
      phi: TensorLike,
      name: str = "spherical_harmonics_evaluate_spherical_harmonics",
  ) -> TensorLike:  # pylint: disable=line-too-long
      """Evaluates a point sample of a Spherical Harmonic basis function.
  
      Note:
        This function is implementating the algorithm and variable names described
        p. 12 of 'Spherical Harmonic Lighting: The Gritty Details.
  
      Note:
        In the following, A1 to An are optional batch dimensions.
  
      Args:
        degree_l: An integer tensor of shape `[A1, ..., An, C]`, where the last
          dimension represents the band of the spherical harmonics. Note that
          `degree_l` must be non-negative.
        order_m: An integer tensor of shape `[A1, ..., An, C]`, where the last
          dimension represents the index of the spherical harmonics in the band
          `degree_l`. Note that `order_m` must satisfy `0 <= order_m <= l`.
        theta: A tensor of shape `[A1, ..., An, 1]`. This variable stores the polar
          angle of the sameple. Values of theta must be in [0, pi].
        phi: A tensor of shape `[A1, ..., An, 1]`. This variable stores the
          azimuthal angle of the sameple. Values of phi must be in [0, 2pi].
        name: A name for this op. Defaults to
          "spherical_harmonics_evaluate_spherical_harmonics".
  
      Returns:
        A tensor of shape `[A1, ..., An, C]` containing the evaluation of each basis
        of the spherical harmonics.
  
      Raises:
        ValueError: if the shape of `theta` or `phi` is not supported.
        InvalidArgumentError: if at least an element of `l`, `m`, `theta` or `phi`
        is outside the expected range.
      """
      with tf.name_scope(name):
          degree_l = tf.convert_to_tensor(value=degree_l)
          order_m = tf.convert_to_tensor(value=order_m)
          theta = tf.convert_to_tensor(value=theta)
          phi = tf.convert_to_tensor(value=phi)
  
          if not degree_l.dtype.is_integer:
              raise ValueError("`degree_l` must be of an integer type.")
          if not order_m.dtype.is_integer:
              raise ValueError("`order_m` must be of an integer type.")
  
          shape.compare_dimensions(
              tensors=(degree_l, order_m),
              axes=-1,
              tensor_names=("degree_l", "order_m"),
          )
          shape.check_static(
              tensor=phi, tensor_name="phi", has_dim_equals=(-1, 1)
          )
          shape.check_static(
              tensor=theta, tensor_name="theta", has_dim_equals=(-1, 1)
          )
          shape.compare_batch_dimensions(
              tensors=(degree_l, order_m, theta, phi),
              last_axes=-2,
              tensor_names=("degree_l", "order_m", "theta", "phi"),
              broadcast_compatible=False,
          )
          # Checks that tensors contain appropriate data.
          degree_l = asserts.assert_all_above(degree_l, 0)
          order_m = asserts.assert_all_in_range(
              order_m, -degree_l, degree_l
          )
          theta = asserts.assert_all_in_range(theta, 0.0, np.pi)
          phi = asserts.assert_all_in_range(phi, 0.0, 2.0 * np.pi)
  
          var_type = theta.dtype
          sign_m = tf.math.sign(order_m)
          order_m = tf.abs(order_m)
          zeros = tf.zeros_like(order_m)
          result_m_zero = _spherical_harmonics_normalization(
              degree_l, zeros, var_type
          ) * evaluate_legendre_polynomial(
              degree_l, zeros, tf.cos(theta)
          )
          result_branch = _evaluate_spherical_harmonics_branch(
              degree_l, order_m, theta, phi, sign_m, var_type
          )
          return tf.where(
              tf.equal(order_m, zeros), result_m_zero, result_branch
          )
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from typing import Tuple
  import numpy
  from six.moves import range
  import tensorflow
  from tensorflow_graphics.math import math_helpers
  from tensorflow_graphics.math import vector
  from tensorflow_graphics.util import asserts
  from tensorflow_graphics.util import export_api
  from tensorflow_graphics.util import shape
  from tensorflow_graphics.util.type_alias import TensorLike
label_desc: Use image node_id 12 for calling a global function with example usage: evaluate_spherical_harmonics(degree_l, order_m, theta, phi, name) and returns: tf