proxsuite-nlp  0.11.0
A primal-dual augmented Lagrangian-type solver for nonlinear programming on manifolds.
 
Loading...
Searching...
No Matches
cartesian-product.hpp
1#pragma once
2
4#include "proxsuite-nlp/third-party/polymorphic_cxx14.hpp"
5
6#include <type_traits>
7
8namespace proxsuite {
9namespace nlp {
10
13template <typename _Scalar>
14struct CartesianProductTpl : ManifoldAbstractTpl<_Scalar> {
15 using Scalar = _Scalar;
16
17 using Base = ManifoldAbstractTpl<Scalar>;
19
20private:
21 std::vector<polymorphic<Base>> m_components;
22
23public:
24 const Base &getComponent(std::size_t i) const { return *m_components[i]; }
25
26 inline std::size_t numComponents() const { return m_components.size(); }
27
28 template <class Concrete> inline void addComponent(const Concrete &c) {
29 static_assert(
30 std::is_base_of_v<Base, Concrete> ||
31 std::is_same_v<Concrete, polymorphic<Base>>,
32 "Input type should either be derived from ManifoldAbstractTpl or be "
33 "polymorphic<ManifoldAbstractTpl>.");
34 m_components.emplace_back(c);
35 }
36
37 inline void addComponent(const CartesianProductTpl &other) {
38 for (const auto &c : other.m_components) {
39 this->addComponent(c);
40 }
41 }
42
43 CartesianProductTpl() = default;
44 CartesianProductTpl(const CartesianProductTpl &) = default;
45 CartesianProductTpl &operator=(const CartesianProductTpl &) = default;
46 CartesianProductTpl(CartesianProductTpl &&) = default;
47 CartesianProductTpl &operator=(CartesianProductTpl &&) = default;
48
49 CartesianProductTpl(const std::vector<polymorphic<Base>> &components)
50 : m_components(components) {}
51
52 CartesianProductTpl(std::initializer_list<polymorphic<Base>> components)
53 : m_components(components) {}
54
55 CartesianProductTpl(const polymorphic<Base> &left,
56 const polymorphic<Base> &right) {
57 addComponent(left);
58 addComponent(right);
59 }
60
61 inline int nx() const {
62 int r = 0;
63 for (std::size_t i = 0; i < numComponents(); i++) {
64 r += m_components[i]->nx();
65 }
66 return r;
67 }
68
69 inline int ndx() const {
70 int r = 0;
71 for (std::size_t i = 0; i < numComponents(); i++) {
72 r += m_components[i]->ndx();
73 }
74 return r;
75 }
76
77 VectorXs neutral() const;
78 VectorXs rand() const;
79 bool isNormalized(const ConstVectorRef &x) const;
80
81private:
82 template <class VectorType, class U = std::remove_const_t<VectorType>>
83 std::vector<U> split_impl(VectorType &x) const;
84
85 template <class VectorType, class U = std::remove_const_t<VectorType>>
86 std::vector<U> split_vector_impl(VectorType &v) const;
87
88public:
89 std::vector<VectorRef> split(VectorRef x) const {
90 return split_impl<VectorRef>(x);
91 }
92
93 std::vector<ConstVectorRef> split(const ConstVectorRef &x) const {
94 return split_impl<const ConstVectorRef>(x);
95 }
96
97 std::vector<VectorRef> split_vector(VectorRef v) const {
98 return split_vector_impl<VectorRef>(v);
99 }
100
101 std::vector<ConstVectorRef> split_vector(const ConstVectorRef &v) const {
102 return split_vector_impl<const ConstVectorRef>(v);
103 }
104
105 VectorXs merge(const std::vector<VectorXs> &xs) const;
106
107 VectorXs merge_vector(const std::vector<VectorXs> &vs) const;
108
109 void integrate_impl(const ConstVectorRef &x, const ConstVectorRef &v,
110 VectorRef out) const;
111
112 void difference_impl(const ConstVectorRef &x0, const ConstVectorRef &x1,
113 VectorRef out) const;
114
115 void Jintegrate_impl(const ConstVectorRef &x, const ConstVectorRef &v,
116 MatrixRef Jout, int arg) const;
117
118 void JintegrateTransport(const ConstVectorRef &x, const ConstVectorRef &v,
119 MatrixRef Jout, int arg) const;
120
121 void Jdifference_impl(const ConstVectorRef &x0, const ConstVectorRef &x1,
122 MatrixRef Jout, int arg) const;
123};
124
125template <typename T>
126auto operator*(const polymorphic<ManifoldAbstractTpl<T>> &left,
127 const polymorphic<ManifoldAbstractTpl<T>> &right) {
128 return CartesianProductTpl<T>(left, right);
129}
130
131template <typename T>
132auto operator*(const CartesianProductTpl<T> &left,
133 const polymorphic<ManifoldAbstractTpl<T>> &right) {
134 CartesianProductTpl<T> out(left);
135 out.addComponent(right);
136 return out;
137}
138
139template <typename T>
140auto operator*(const polymorphic<ManifoldAbstractTpl<T>> &left,
141 const CartesianProductTpl<T> &right) {
142 return right * left;
143}
144
145template <typename T>
146auto operator*(const CartesianProductTpl<T> &left,
147 const CartesianProductTpl<T> &right) {
148 CartesianProductTpl<T> out{left};
149 out.addComponent(right);
150 return out;
151}
152
153} // namespace nlp
154} // namespace proxsuite
155
156// implementation details
157#include "proxsuite-nlp/modelling/spaces/cartesian-product.hxx"
158
159#ifdef PROXSUITE_NLP_ENABLE_TEMPLATE_INSTANTIATION
160#include "proxsuite-nlp/modelling/spaces/cartesian-product.txx"
161#endif
#define PROXSUITE_NLP_DYNAMIC_TYPEDEFS(Scalar)
Definition math.hpp:26
Main package namespace.
Definition bcl-params.hpp:5
The cartesian product of two or more manifolds.
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.