docstr: Map a point in the product to points in each factor.
  
  Parameters
  ----------
  point : array-like, shape (..., shape)
      The point to be projected to the factors
  
  Returns
  -------
  projected_points : list of array-like
      The points on each factor, of shape (..., factor.shape)
  
  Raises
  ------
  ShapeError
      If the point does not have a shape compatible with the product manifold.
docstr_tok: ["Map","a","point","in","the","product","to","points","in","each","factor",".","Parameters","--","--","--","--","--","point",":","array-like",",","shape","(","...",",","shape",")","The","point","to","be","projected","to","the","factors","Returns","--","--","--","-","projected_points",":","list","of","array-like","The","points","on","each","factor",",","of","shape","(","...",",","factor.shape",")","Raises","--","--","--","ShapeError","If","the","point","does","not","have","a","shape","compatible","with","the","product","manifold","."]
code: def project_from_product(self, point):
      """Map a point in the product to points in each factor.
  
      Parameters
      ----------
      point : array-like, shape (..., shape)
          The point to be projected to the factors
  
      Returns
      -------
      projected_points : list of array-like
          The points on each factor, of shape (..., factor.shape)
  
      Raises
      ------
      ShapeError
          If the point does not have a shape compatible with the product manifold.
      """
      geomstats.errors.check_point_shape(point, self)
  
      if self.default_point_type == "vector":
          projected_points = gs.split(point, self._cum_index, axis=-1)
          projected_points = [
              self._reshape_trailing(
                  projected_points[j], self.factors[j]
              )
              for j in range(len(self.factors))
          ]
  
      else:
          splitting_axis = -1 * len(self.shape)
          projected_points = gs.split(
              point, len(self.factors), axis=splitting_axis
          )
          projected_points = [
              gs.squeeze(projected_point, axis=splitting_axis)
              for projected_point in projected_points
          ]
  
      if self._has_mixed_fields:
          for i, (factor, projected_point) in enumerate(
              zip(self.factors, projected_points)
          ):
              if not _factor_is_complex(factor):
                  projected_points[i] = gs.real(projected_point)
  
      return projected_points
  
imports: import math
  import geomstats.backend
  import geomstats.errors
  from geomstats.geometry.complex_manifold import ComplexManifold
  from geomstats.geometry.complex_riemannian_metric import ComplexRiemannianMetric
  from geomstats.geometry.manifold import Manifold
  from geomstats.geometry.riemannian_metric import RiemannianMetric
  from geomstats.vectorization import get_batch_shape
label_desc: Use image node_id 3 for calling the _IterateOverFactorsMixins obj's underlying member method code with example usage: obj.project_from_product(point) and returns: projected_points