3#include "proxsuite-nlp/modelling/spaces/cartesian-product.hpp" 
    8template <
typename Scalar>
 
   10  VectorXs out(this->
nx());
 
   12  for (std::size_t i = 0; i < numComponents(); i++) {
 
   13    const long n = m_components[i]->nx();
 
   14    out.segment(c, n) = m_components[i]->neutral();
 
 
   20template <
typename Scalar>
 
   22  VectorXs out(this->
nx());
 
   24  for (std::size_t i = 0; i < numComponents(); i++) {
 
   25    const long n = m_components[i]->nx();
 
   26    out.segment(c, n) = m_components[i]->rand();
 
 
   32template <
typename Scalar>
 
   35  auto xs = this->split(x);
 
   36  for (std::size_t i = 0; i < numComponents(); i++) {
 
   37    res |= m_components[i]->isNormalized(xs[i]);
 
 
   42template <
typename Scalar>
 
   43template <
class VectorType, 
class U>
 
   44std::vector<U> CartesianProductTpl<Scalar>::split_impl(VectorType &x)
 const {
 
   45  PROXSUITE_NLP_DIM_CHECK(x, this->nx());
 
   48  for (std::size_t i = 0; i < numComponents(); i++) {
 
   49    const long n = m_components[i]->nx();
 
   50    out.push_back(x.segment(c, n));
 
   56template <
typename Scalar>
 
   57template <
class VectorType, 
class U>
 
   59CartesianProductTpl<Scalar>::split_vector_impl(VectorType &v)
 const {
 
   60  PROXSUITE_NLP_DIM_CHECK(v, this->ndx());
 
   63  for (std::size_t i = 0; i < numComponents(); i++) {
 
   64    const long n = m_components[i]->ndx();
 
   65    out.push_back(v.segment(c, n));
 
   71template <
typename Scalar>
 
   72auto CartesianProductTpl<Scalar>::merge(
const std::vector<VectorXs> &xs) 
const 
   74  VectorXs out(this->nx());
 
   76  for (std::size_t i = 0; i < numComponents(); i++) {
 
   77    const long n = m_components[i]->nx();
 
   78    out.segment(c, n) = xs[i];
 
   84template <
typename Scalar>
 
   85auto CartesianProductTpl<Scalar>::merge_vector(
 
   86    const std::vector<VectorXs> &vs) 
const -> VectorXs {
 
   87  VectorXs out(this->ndx());
 
   89  for (std::size_t i = 0; i < numComponents(); i++) {
 
   90    const long n = m_components[i]->ndx();
 
   91    out.segment(c, n) = vs[i];
 
   97template <
typename Scalar>
 
   99                                                 const ConstVectorRef &v,
 
  100                                                 VectorRef out)
 const {
 
  101  assert(
nx() == out.size());
 
  102  Eigen::Index cq = 0, cv = 0;
 
  103  for (std::size_t i = 0; i < numComponents(); i++) {
 
  104    const long nq = getComponent(i).nx();
 
  105    const long nv = getComponent(i).ndx();
 
  106    auto sx = x.segment(cq, nq);
 
  107    auto sv = v.segment(cv, nv);
 
  109    auto sout = out.segment(cq, nq);
 
  111    getComponent(i).integrate(sx, sv, sout);
 
  117template <
typename Scalar>
 
  119                                                  const ConstVectorRef &x1,
 
  120                                                  VectorRef out)
 const {
 
  121  assert(
ndx() == out.size());
 
  122  Eigen::Index cq = 0, cv = 0;
 
  123  for (std::size_t i = 0; i < numComponents(); i++) {
 
  124    const long nq = getComponent(i).nx();
 
  125    const long nv = getComponent(i).ndx();
 
  126    auto sx0 = x0.segment(cq, nq);
 
  127    auto sx1 = x1.segment(cq, nq);
 
  129    auto sout = out.segment(cv, nv);
 
  131    getComponent(i).difference(sx0, sx1, sout);
 
 
 
  137template <
typename Scalar>
 
  138void CartesianProductTpl<Scalar>::Jintegrate_impl(
const ConstVectorRef &x,
 
  139                                                  const ConstVectorRef &v,
 
  142  assert(ndx() == Jout.rows());
 
  144  Eigen::Index cq = 0, cv = 0;
 
  145  for (std::size_t i = 0; i < numComponents(); i++) {
 
  146    const long nq = getComponent(i).nx();
 
  147    const long nv = getComponent(i).ndx();
 
  148    auto sx = x.segment(cq, nq);
 
  149    auto sv = v.segment(cv, nv);
 
  151    auto sJout = Jout.block(cv, cv, nv, nv);
 
  153    getComponent(i).Jintegrate(sx, sv, sJout, arg);
 
  159template <
typename Scalar>
 
  161                                                      const ConstVectorRef &v,
 
  164  Eigen::Index cq = 0, cv = 0;
 
  165  for (std::size_t i = 0; i < numComponents(); i++) {
 
  166    const long nq = m_components[i]->nx();
 
  167    auto sx = x.segment(cq, nq);
 
  170    const long nv = m_components[i]->ndx();
 
  171    auto sv = v.segment(cv, nv);
 
  172    auto sJout = Jout.middleRows(cv, nv);
 
  175    getComponent(i).JintegrateTransport(sx, sv, sJout, arg);
 
 
  179template <
typename Scalar>
 
  180void CartesianProductTpl<Scalar>::Jdifference_impl(
const ConstVectorRef &x0,
 
  181                                                   const ConstVectorRef &x1,
 
  184  assert(ndx() == Jout.rows());
 
  186  Eigen::Index cq = 0, cv = 0;
 
  187  for (std::size_t i = 0; i < numComponents(); i++) {
 
  188    const long nq = m_components[i]->nx();
 
  189    auto sx0 = x0.segment(cq, nq);
 
  190    auto sx1 = x1.segment(cq, nq);
 
  193    const long nv = m_components[i]->ndx();
 
  194    auto sJout = Jout.block(cv, cv, nv, nv);
 
  197    getComponent(i).Jdifference(sx0, sx1, sJout, arg);
 
 
 
 
 
 
void difference_impl(const ConstVectorRef &x0, const ConstVectorRef &x1, VectorRef out) const
Implementation of the manifold retraction operation.
 
VectorXs rand() const
Sample a random point  on the manifold.
 
VectorXs neutral() const
Get the neutral element  from the manifold (if this makes sense).
 
int ndx() const
Get manifold tangent space dimension.
 
int nx() const
Get manifold representation dimension.
 
void integrate_impl(const ConstVectorRef &x, const ConstVectorRef &v, VectorRef out) const
Perform the manifold integration operation.
 
void JintegrateTransport(const ConstVectorRef &x, const ConstVectorRef &v, MatrixRef Jout, int arg) const
Perform the parallel transport operation.
 
bool isNormalized(const ConstVectorRef &x) const
Check if the input vector x is a viable element of the manifold.