class_docstr: Elastic metric defined by a family of second order Sobolev metrics.
  
  Each individual discrete surface is represented by a 2D-array of shape
  `[n_vertices, 3]`. See [HSKCB2022]_ for details.
  
  The parameters a0, a1, b1, c1, d1, a2 (detailed below) are non-negative weighting
  coefficients for the different terms in the metric.
  
  Parameters
  ----------
  space : DiscreteSurfaces
      Instantiated DiscreteSurfaces manifold.
  a0 : float
      First order parameter.
      Default: 1.
  a1 : float
      Stretching parameter.
      Default: 1.
  b1 : float
      Shearing parameter.
      Default: 1.
  c1 : float
      Bending parameter.
      Default: 1.
  d1 : float
      Additonal first order parameter.
      Default: 1.
  a2 : float
      Second order parameter.
      Default: 1.
  
  References
  ----------
  .. [HSKCB2022] "Elastic shape analysis of surfaces with second-order
      Sobolev metrics: a comprehensive numerical framework".
      arXiv:2204.04238 [cs.CV], 25 Sep 2022
class_docstr_tok: ["Elastic","metric","defined","by","a","family","of","second","order","Sobolev","metrics",".","Each","individual","discrete","surface","is","represented","by","a","2D-array","of","shape","`","[","n_vertices",",","3","]","`",".","See","[","HSKCB2022","]","_","for","details",".","The","parameters","a0",",","a1",",","b1",",","c1",",","d1",",","a2","(","detailed","below",")","are","non-negative","weighting","coefficients","for","the","different","terms","in","the","metric",".","Parameters","--","--","--","--","--","space",":","DiscreteSurfaces","Instantiated","DiscreteSurfaces","manifold",".","a0",":","float","First","order","parameter",".","Default",":","1.","a1",":","float","Stretching","parameter",".","Default",":","1.","b1",":","float","Shearing","parameter",".","Default",":","1.","c1",":","float","Bending","parameter",".","Default",":","1.","d1",":","float","Additonal","first","order","parameter",".","Default",":","1.","a2",":","float","Second","order","parameter",".","Default",":","1",".","References","--","--","--","--","--","..","[","HSKCB2022","]","``","Elastic","shape","analysis","of","surfaces","with","second-order","Sobolev","metrics",":","a","comprehensive","numerical","framework","''",".","arXiv:2204.04238","[","cs.CV","]",",","25","Sep","2022"]
docstr: Compute inner product between two tangent vectors at a base point.
  
  The inner-product has 6 terms, where each term corresponds to
  one of the 6 hyperparameters a0, a1, b1, c1, d1, a2.
  
  We denote h and k the tangent vectors a and b respectively.
  We denote q the base point, i.e. the surface.
  
  The six terms of the inner-product are given by:
  :math:`\int_M (G_{a_0} + G_{a_1} + G_{b_1} + G_{c_1} + G_{d_1} + G_{a_2})vol_q`
  
  where:
  
  - :math:`G_{a_0} = a_0 <h, k>`
  - :math:`G_{a_1} = a_1.g_q^{-1} <dh_m, dk_m>`
  - :math:`G_{b_1} = b_1.g_q^{-1} <dh_+, dk_+>`
  - :math:`G_{c_1} = c_1.g_q^{-1} <dh_\perp, dk_\perp>`
  - :math:`G_{d_1} = d_1.g_q^{-1} <dh_0, dk_0>`
  - :math:`G_{a_2} = a_2 <\Delta_q h, \Delta_q k>`
  
  with notations taken from [HSKCB2022]_.
  
  Parameters
  ----------
  tangent_vec_a : array-like, shape=[..., n_vertices, 3]
      Tangent vector at base point.
  tangent_vec_b : array-like, shape=[..., n_vertices, 3]
      Tangent vector at base point.
  base_point : array-like, shape=[n_vertices, 3]
      Surface, as the 3D coordinates of the vertices of its triangulation.
  
  Returns
  -------
  inner_prod : array-like, shape=[...]
      Inner-product.
  
  References
  ----------
  .. [HSKCB2022] "Elastic shape analysis of surfaces with second-order
      Sobolev metrics: a comprehensive numerical framework".
      arXiv:2204.04238 [cs.CV], 25 Sep 2022.
docstr_tok: ["Compute","inner","product","between","two","tangent","vectors","at","a","base","point",".","The","inner-product","has","6","terms",",","where","each","term","corresponds","to","one","of","the","6","hyperparameters","a0",",","a1",",","b1",",","c1",",","d1",",","a2",".","We","denote","h","and","k","the","tangent","vectors","a","and","b","respectively",".","We","denote","q","the","base","point",",","i.e",".","the","surface",".","The","six","terms","of","the","inner-product","are","given","by",":",":","math",":","`","\\int_M","(","G_","{","a_0","}","+","G_","{","a_1","}","+","G_","{","b_1","}","+","G_","{","c_1","}","+","G_","{","d_1","}","+","G_","{","a_2","}",")","vol_q","`","where",":","-",":","math",":","`","G_","{","a_0","}","=","a_0","<","h",",","k",">","`","-",":","math",":","`","G_","{","a_1","}","=","a_1.g_q^","{","-1","}","<","dh_m",",","dk_m",">","`","-",":","math",":","`","G_","{","b_1","}","=","b_1.g_q^","{","-1","}","<","dh_+",",","dk_+",">","`","-",":","math",":","`","G_","{","c_1","}","=","c_1.g_q^","{","-1","}","<","dh_\\perp",",","dk_\\perp",">","`","-",":","math",":","`","G_","{","d_1","}","=","d_1.g_q^","{","-1","}","<","dh_0",",","dk_0",">","`","-",":","math",":","`","G_","{","a_2","}","=","a_2","<","\\Delta_q","h",",","\\Delta_q","k",">","`","with","notations","taken","from","[","HSKCB2022","]","_.","Parameters","--","--","--","--","--","tangent_vec_a",":","array-like",",","shape=","[","...",",","n_vertices",",","3","]","Tangent","vector","at","base","point",".","tangent_vec_b",":","array-like",",","shape=","[","...",",","n_vertices",",","3","]","Tangent","vector","at","base","point",".","base_point",":","array-like",",","shape=","[","n_vertices",",","3","]","Surface",",","as","the","3D","coordinates","of","the","vertices","of","its","triangulation",".","Returns","--","--","--","-","inner_prod",":","array-like",",","shape=","[","...","]","Inner-product",".","References","--","--","--","--","--","..","[","HSKCB2022","]","``","Elastic","shape","analysis","of","surfaces","with","second-order","Sobolev","metrics",":","a","comprehensive","numerical","framework","''",".","arXiv:2204.04238","[","cs.CV","]",",","25","Sep","2022","."]
code: def inner_product(self, tangent_vec_a, tangent_vec_b, base_point):
      r"""Compute inner product between two tangent vectors at a base point.
  
      The inner-product has 6 terms, where each term corresponds to
      one of the 6 hyperparameters a0, a1, b1, c1, d1, a2.
  
      We denote h and k the tangent vectors a and b respectively.
      We denote q the base point, i.e. the surface.
  
      The six terms of the inner-product are given by:
      :math:`\int_M (G_{a_0} + G_{a_1} + G_{b_1} + G_{c_1} + G_{d_1} + G_{a_2})vol_q`
  
      where:
  
      - :math:`G_{a_0} = a_0 <h, k>`
      - :math:`G_{a_1} = a_1.g_q^{-1} <dh_m, dk_m>`
      - :math:`G_{b_1} = b_1.g_q^{-1} <dh_+, dk_+>`
      - :math:`G_{c_1} = c_1.g_q^{-1} <dh_\perp, dk_\perp>`
      - :math:`G_{d_1} = d_1.g_q^{-1} <dh_0, dk_0>`
      - :math:`G_{a_2} = a_2 <\Delta_q h, \Delta_q k>`
  
      with notations taken from [HSKCB2022]_.
  
      Parameters
      ----------
      tangent_vec_a : array-like, shape=[..., n_vertices, 3]
          Tangent vector at base point.
      tangent_vec_b : array-like, shape=[..., n_vertices, 3]
          Tangent vector at base point.
      base_point : array-like, shape=[n_vertices, 3]
          Surface, as the 3D coordinates of the vertices of its triangulation.
  
      Returns
      -------
      inner_prod : array-like, shape=[...]
          Inner-product.
  
      References
      ----------
      .. [HSKCB2022] "Elastic shape analysis of surfaces with second-order
          Sobolev metrics: a comprehensive numerical framework".
          arXiv:2204.04238 [cs.CV], 25 Sep 2022.
      """
      to_squeeze = False
      if tangent_vec_a.ndim == 2 and tangent_vec_b.ndim == 2:
          to_squeeze = True
      if tangent_vec_a.ndim == 2:
          tangent_vec_a = gs.expand_dims(tangent_vec_a, axis=0)
      if tangent_vec_b.ndim == 2:
          tangent_vec_b = gs.expand_dims(tangent_vec_b, axis=0)
  
      point_a = base_point + tangent_vec_a
      point_b = base_point + tangent_vec_b
      inner_prod = gs.zeros(
          (1, gs.maximum(len(tangent_vec_a), len(tangent_vec_b)))
      )
      if self.a0 > 0 or self.a2 > 0:
          vertex_areas_bp = self._space.vertex_areas(base_point)
          if self.a0 > 0:
              inner_prod += self._inner_product_a0(
                  tangent_vec_a,
                  tangent_vec_b,
                  vertex_areas_bp=vertex_areas_bp,
              )
          if self.a2 > 0:
              inner_prod += self._inner_product_a2(
                  tangent_vec_a,
                  tangent_vec_b,
                  base_point=base_point,
                  vertex_areas_bp=vertex_areas_bp,
              )
      if self.a1 > 0 or self.b1 > 0 or self.c1 > 0 or self.b1 > 0:
          one_forms_bp = self._space.surface_one_forms(base_point)
          surface_metrics_bp = (
              self._space._surface_metric_matrices_from_one_forms(
                  one_forms_bp
              )
          )
          normals_bp = self._space.normals(base_point)
          areas_bp = gs.sqrt(gs.linalg.det(surface_metrics_bp))
  
          if self.c1 > 0:
              inner_prod += self._inner_product_c1(
                  point_a, point_b, normals_bp, areas_bp
              )
          if self.d1 > 0 or self.b1 > 0 or self.a1 > 0:
              ginv_bp = gs.linalg.inv(surface_metrics_bp)
              one_forms_a = self._space.surface_one_forms(point_a)
              one_forms_b = self._space.surface_one_forms(point_b)
              if self.d1 > 0:
                  inner_prod += self._inner_product_d1(
                      one_forms_a,
                      one_forms_b,
                      one_forms_bp,
                      areas_bp=areas_bp,
                      inv_surface_metrics_bp=ginv_bp,
                  )
  
              if self.b1 > 0 or self.a1 > 0:
                  dga = (
                      gs.matmul(
                          one_forms_a,
                          gs.transpose(one_forms_a, axes=(0, 1, 3, 2)),
                      )
                      - surface_metrics_bp
                  )
                  dgb = (
                      gs.matmul(
                          one_forms_b,
                          gs.transpose(one_forms_b, axes=(0, 1, 3, 2)),
                      )
                      - surface_metrics_bp
                  )
                  ginvdga = gs.matmul(ginv_bp, dga)
                  ginvdgb = gs.matmul(ginv_bp, dgb)
                  inner_prod += self._inner_product_a1(
                      ginvdga, ginvdgb, areas_bp
                  )
                  inner_prod += self._inner_product_b1(
                      ginvdga, ginvdgb, areas_bp
                  )
      return (
          gs.squeeze(inner_prod, axis=0) if to_squeeze else inner_prod
      )
  
imports: import math
  import geomstats.backend
  from geomstats.geometry.euclidean import Euclidean
  from geomstats.geometry.manifold import Manifold
  from geomstats.geometry.riemannian_metric import RiemannianMetric
  from geomstats.numerics.optimizers import ScipyMinimize
label_desc: Use image node_id 8 for calling the ElasticMetric obj's underlying member method code with example usage: obj.inner_product(tangent_vec_a, tangent_vec_b, base_point) and returns: unknown