class_docstr: Class for the Fisher information metric on Dirichlet distributions.
class_docstr_tok: ["Class","for","the","Fisher","information","metric","on","Dirichlet","distributions","."]
docstr: Solve approximation of the geodesic boundary value problem.
  
  The space of solutions is restricted to curves whose coordinates are
  polynomial functions of time. The boundary value problem is solved by
  minimizing the energy among all such curves starting from initial_point
  and ending at end_point, i.e. curves t -> (x_1(t),...,x_n(t)) where x_i
  are polynomial functions of time t, such that (x_1(0),..., x_n(0)) is
  initial_point and (x_1(1),..., x_n(1)) is end_point. The parameterized
  curve is computed at n_times discrete times.
  
  Parameters
  ----------
  initial_point : array-like, shape=(dim,)
      Starting point of the geodesic.
  end_point : array-like, shape=(dim,)
      End point of the geodesic.
  degree : int
      Degree of the coordinates' polynomial functions of time.
  method : str
      Minimization method to use in scipy.optimize.minimize.
  n_times : int
      Number of sample times.
  jac_on : bool
      If jac_on=True, use the Jacobian of the energy cost function in
      scipy.optimize.minimize.
  
  Returns
  -------
  dist : float
      Length of the polynomial approximation of the geodesic.
  curve : array-like, shape=(n_times, dim)
      Polynomial approximation of the geodesic.
  velocity : array-like, shape=(n_times, dim)
      Velocity of the polynomial approximation of the geodesic.
docstr_tok: ["Solve","approximation","of","the","geodesic","boundary","value","problem",".","The","space","of","solutions","is","restricted","to","curves","whose","coordinates","are","polynomial","functions","of","time",".","The","boundary","value","problem","is","solved","by","minimizing","the","energy","among","all","such","curves","starting","from","initial_point","and","ending","at","end_point",",","i.e",".","curves","t","-",">","(","x_1","(","t",")",",","...",",","x_n","(","t",")",")","where","x_i","are","polynomial","functions","of","time","t",",","such","that","(","x_1","(","0",")",",","...",",","x_n","(","0",")",")","is","initial_point","and","(","x_1","(","1",")",",","...",",","x_n","(","1",")",")","is","end_point",".","The","parameterized","curve","is","computed","at","n_times","discrete","times",".","Parameters","--","--","--","--","--","initial_point",":","array-like",",","shape=","(","dim",",",")","Starting","point","of","the","geodesic",".","end_point",":","array-like",",","shape=","(","dim",",",")","End","point","of","the","geodesic",".","degree",":","int","Degree","of","the","coordinates","'","polynomial","functions","of","time",".","method",":","str","Minimization","method","to","use","in","scipy.optimize.minimize",".","n_times",":","int","Number","of","sample","times",".","jac_on",":","bool","If","jac_on=True",",","use","the","Jacobian","of","the","energy","cost","function","in","scipy.optimize.minimize",".","Returns","--","--","--","-","dist",":","float","Length","of","the","polynomial","approximation","of","the","geodesic",".","curve",":","array-like",",","shape=","(","n_times",",","dim",")","Polynomial","approximation","of","the","geodesic",".","velocity",":","array-like",",","shape=","(","n_times",",","dim",")","Velocity","of","the","polynomial","approximation","of","the","geodesic","."]
code: def _approx_geodesic_bvp(
      self,
      initial_point,
      end_point,
      degree=5,
      method="BFGS",
      n_times=200,
      jac_on=True,
  ):
      """Solve approximation of the geodesic boundary value problem.
  
      The space of solutions is restricted to curves whose coordinates are
      polynomial functions of time. The boundary value problem is solved by
      minimizing the energy among all such curves starting from initial_point
      and ending at end_point, i.e. curves t -> (x_1(t),...,x_n(t)) where x_i
      are polynomial functions of time t, such that (x_1(0),..., x_n(0)) is
      initial_point and (x_1(1),..., x_n(1)) is end_point. The parameterized
      curve is computed at n_times discrete times.
  
      Parameters
      ----------
      initial_point : array-like, shape=(dim,)
          Starting point of the geodesic.
      end_point : array-like, shape=(dim,)
          End point of the geodesic.
      degree : int
          Degree of the coordinates' polynomial functions of time.
      method : str
          Minimization method to use in scipy.optimize.minimize.
      n_times : int
          Number of sample times.
      jac_on : bool
          If jac_on=True, use the Jacobian of the energy cost function in
          scipy.optimize.minimize.
  
      Returns
      -------
      dist : float
          Length of the polynomial approximation of the geodesic.
      curve : array-like, shape=(n_times, dim)
          Polynomial approximation of the geodesic.
      velocity : array-like, shape=(n_times, dim)
          Velocity of the polynomial approximation of the geodesic.
      """
  
      def cost_fun(param):
          """Compute the energy of the polynomial curve defined by param.
  
          Parameters
          ----------
          param : array-like, shape=(degree - 1, dim)
              Parameters of the curve coordinates' polynomial functions of time.
  
          Returns
          -------
          energy : float
              Energy of the polynomial approximation of the geodesic.
          length : float
              Length of the polynomial approximation of the geodesic.
          curve : array-like, shape=(n_times, dim)
              Polynomial approximation of the geodesic.
          velocity : array-like, shape=(n_times, dim)
              Velocity of the polynomial approximation of the geodesic.
          """
          last_coef = end_point - initial_point - gs.sum(param, axis=0)
          coef = gs.vstack((initial_point, param, last_coef))
  
          t = gs.linspace(0.0, 1.0, n_times)
          t_curve = [t**i for i in range(degree + 1)]
          t_curve = gs.stack(t_curve)
          curve = gs.einsum("ij,ik->kj", coef, t_curve)
  
          t_velocity = [i * t ** (i - 1) for i in range(1, degree + 1)]
          t_velocity = gs.stack(t_velocity)
          velocity = gs.einsum("ij,ik->kj", coef[1:], t_velocity)
  
          if curve.min() < 0:
              return np.inf, np.inf, curve, np.nan
  
          velocity_sqnorm = self.squared_norm(
              vector=velocity, base_point=curve
          )
          length = gs.sum(velocity_sqnorm ** (1 / 2)) / n_times
          energy = gs.sum(velocity_sqnorm) / n_times
          return energy, length, curve, velocity
  
      def cost_jacobian(param):
          """Compute the jacobian of the cost function at polynomial curve.
  
          Parameters
          ----------
          param : array-like, shape=(degree - 1, dim)
              Parameters of the curve coordinates' polynomial functions of time.
  
          Returns
          -------
          jac : array-like, shape=(dim * (degree - 1),)
              Jacobian of the cost function at polynomial curve.
          """
          last_coef = end_point - initial_point - gs.sum(param, 0)
          coef = gs.vstack((initial_point, param, last_coef))
  
          t = gs.linspace(0.0, 1.0, n_times)
          t_position = [t**i for i in range(degree + 1)]
          t_position = gs.stack(t_position)
          position = gs.einsum("ij,ik->kj", coef, t_position)
  
          t_velocity = [i * t ** (i - 1) for i in range(1, degree + 1)]
          t_velocity = gs.stack(t_velocity)
          velocity = gs.einsum("ij,ik->kj", coef[1:], t_velocity)
  
          fac1 = gs.stack(
              [
                  k * t ** (k - 1) - degree * t ** (degree - 1)
                  for k in range(1, degree)
              ]
          )
          fac2 = gs.stack(
              [t**k - t**degree for k in range(1, degree)]
          )
          fac3 = (velocity * gs.polygamma(1, position)).T - gs.sum(
              velocity, 1
          ) * gs.polygamma(1, gs.sum(position, 1))
          fac4 = (velocity**2 * gs.polygamma(2, position)).T - gs.sum(
              velocity, 1
          ) ** 2 * gs.polygamma(2, gs.sum(position, 1))
  
          cost_jac = (
              2 * gs.einsum("ij,kj->ik", fac1, fac3)
              + gs.einsum("ij,kj->ik", fac2, fac4)
          ) / n_times
          return cost_jac.T.reshape(dim * (degree - 1))
  
      def f2minimize(x):
          """Compute function to minimize."""
          param = gs.transpose(x.reshape((dim, degree - 1)))
          res = cost_fun(param)
          return res[0]
  
      def jacobian(x):
          """Compute jacobian of the function to minimize."""
          param = gs.transpose(x.reshape((dim, degree - 1)))
          return cost_jacobian(param)
  
      dim = initial_point.shape[0]
      x0 = gs.ones(dim * (degree - 1))
      jac = jacobian if jac_on else None
      sol = minimize(f2minimize, x0, method=method, jac=jac)
      opt_param = sol.x.reshape((dim, degree - 1)).T
      _, dist, curve, velocity = cost_fun(opt_param)
  
      return dist, curve, velocity
  
imports: import math
  import numpy
  from scipy.optimize import minimize
  from scipy.stats import dirichlet
  import geomstats.backend
  from geomstats.algebra_utils import from_vector_to_diagonal_matrix
  from geomstats.geometry.base import VectorSpaceOpenSet
  from geomstats.geometry.euclidean import Euclidean
  from geomstats.geometry.riemannian_metric import RiemannianMetric
  from geomstats.information_geometry.base import InformationManifoldMixin, ScipyMultivariateRandomVariable
  from geomstats.numerics.bvp import ScipySolveBVP
  from geomstats.numerics.geodesic import ExpODESolver, LogODESolver
  from geomstats.numerics.ivp import ScipySolveIVP
  from geomstats.vectorization import repeat_out
label_desc: Use image node_id 6 for calling the DirichletMetric obj's underlying member method code with example usage: obj._approx_geodesic_bvp(initial_point, end_point, degree, method, n_times, jac_on) and returns: dist,  curve,  velocity, energy,  length,  curve,  velocity, cost_jac, res, cost_jacobian, np,  np,  curve,  np