class_docstr: Class for a product of manifolds M_1 x ... x M_n.
  
  In contrast to the classes NFoldManifold, Landmarks, or DiscretizedCurves,
  the manifolds M_1, ..., M_n need not be the same, nor of
  same dimension, but the list of manifolds needs to be provided.
  
  Parameters
  ----------
  factors : list
      List of manifolds in the product.
  default_point_type : {'auto', 'vector', 'matrix', 'other'}
      Optional. Default value is 'auto', which will implement as 'vector' unless all
      factors have the same shape. Vector representation gives the point as a 1-d
      array. Matrix representation allows for a point to be represented by an array of
      shape (n, dim), if each manifold has default_point_type 'vector' with shape
      (dim,). 'other' will behave as `matrix` but for higher dimensions.
class_docstr_tok: ["Class","for","a","product","of","manifolds","M_1","x","...","x","M_n",".","In","contrast","to","the","classes","NFoldManifold",",","Landmarks",",","or","DiscretizedCurves",",","the","manifolds","M_1",",","...",",","M_n","need","not","be","the","same",",","nor","of","same","dimension",",","but","the","list","of","manifolds","needs","to","be","provided",".","Parameters","--","--","--","--","--","factors",":","list","List","of","manifolds","in","the","product",".","default_point_type",":","{","'auto","'",",","'vector","'",",","'matrix","'",",","'other","'","}","Optional",".","Default","value","is","'auto","'",",","which","will","implement","as","'vector","'","unless","all","factors","have","the","same","shape",".","Vector","representation","gives","the","point","as","a","1-d","array",".","Matrix","representation","allows","for","a","point","to","be","represented","by","an","array","of","shape","(","n",",","dim",")",",","if","each","manifold","has","default_point_type","'vector","'","with","shape","(","dim",",",")",".","'other","'","will","behave","as","`","matrix","`","but","for","higher","dimensions","."]
docstr: Collect outputs for each product to be returned.
  
  If each element of the output is a boolean array of the same shape, test along
  the list whether all elements are True and return a boolean array of the same
  shape.
  
  Otherwise, if each element of the output has a shape compatible with points of
  the corresponding factor, an attempt is made to map the list of points to a
  point in the product by embed_to_product.
  
  Parameters
  ----------
  outputs : list
      A list of outputs which must be pooled
  
  Returns
  -------
  pooled_output : array-like, shape {(...,), (..., self.shape)}
docstr_tok: ["Collect","outputs","for","each","product","to","be","returned",".","If","each","element","of","the","output","is","a","boolean","array","of","the","same","shape",",","test","along","the","list","whether","all","elements","are","True","and","return","a","boolean","array","of","the","same","shape",".","Otherwise",",","if","each","element","of","the","output","has","a","shape","compatible","with","points","of","the","corresponding","factor",",","an","attempt","is","made","to","map","the","list","of","points","to","a","point","in","the","product","by","embed_to_product",".","Parameters","--","--","--","--","--","outputs",":","list","A","list","of","outputs","which","must","be","pooled","Returns","--","--","--","-","pooled_output",":","array-like",",","shape","{","(","...",",",")",",","(","...",",","self.shape",")","}"]
code: def _pool_outputs_from_function(self, outputs):
      """Collect outputs for each product to be returned.
  
      If each element of the output is a boolean array of the same shape, test along
      the list whether all elements are True and return a boolean array of the same
      shape.
  
      Otherwise, if each element of the output has a shape compatible with points of
      the corresponding factor, an attempt is made to map the list of points to a
      point in the product by embed_to_product.
  
      Parameters
      ----------
      outputs : list
          A list of outputs which must be pooled
  
      Returns
      -------
      pooled_output : array-like, shape {(...,), (..., self.shape)}
      """
      # TODO: simplify after cleaning gs.squeeze
      all_arrays = gs.all(
          [gs.is_array(factor_output) for factor_output in outputs]
      )
      if (
          all_arrays
          and _all_equal(
              [factor_output.shape for factor_output in outputs]
          )
          and gs.all(
              [gs.is_bool(factor_output) for factor_output in outputs]
          )
          or (not all_arrays)
      ):
          outputs = gs.stack(
              [gs.array(factor_output) for factor_output in outputs]
          )
          outputs = gs.all(outputs, axis=0)
          return outputs
  
      try:
          return self.embed_to_product(outputs)
      except geomstats.errors.ShapeError:
          raise RuntimeError(
              "Could not combine outputs - they are not points of the individual"
              " factors."
          )
      except ValueError:
          raise RuntimeError(
              "Could not combine outputs, probably because they could"
              " not be concatenated or stacked."
          )
  
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 ProductManifold obj's underlying member method code with example usage: obj._pool_outputs_from_function(outputs) and returns: outputs, self