1#ifndef INCLUDE_RICCATI_UTILS_HPP
2#define INCLUDE_RICCATI_UTILS_HPP
14 = std::decay_t<T>::RowsAtCompileTime * std::decay_t<T>::ColsAtCompileTime;
39template <
typename Scalar,
typename Vector>
40inline auto scale(Vector&& x, Scalar x0, Scalar h) {
41 return (x0 + h / 2.0 + h / 2.0 * x.array()).matrix();
47template <
typename Scalar>
49template <
typename Scalar>
52template <
typename Scalar>
55template <
typename Scalar>
57template <
typename Scalar>
59template <
typename Scalar>
63inline constexpr T
pi() {
64 return static_cast<T
>(3.141592653589793238462643383279);
67inline double eval(
double x) {
return x; }
69inline std::complex<T>&
eval(std::complex<T>& x) {
73inline std::complex<T>
eval(std::complex<T>&& x) {
82template <
typename T, Eigen::Index R, Eigen::Index C>
83inline Eigen::Matrix<T, R, C>
eval(Eigen::Matrix<T, R, C>&& x) {
87template <
typename T, Eigen::Index R, Eigen::Index C>
88inline auto&
eval(Eigen::Matrix<T, R, C>& x) {
92template <
typename T, Eigen::Index R, Eigen::Index C>
93inline const auto&
eval(
const Eigen::Matrix<T, R, C>& x) {
97template <
typename T, Eigen::Index R, Eigen::Index C>
98inline Eigen::Array<T, R, C>
eval(Eigen::Array<T, R, C>&& x) {
102template <
typename T, Eigen::Index R, Eigen::Index C>
103inline auto&
eval(Eigen::Array<T, R, C>& x) {
107template <
typename T, Eigen::Index R, Eigen::Index C>
108inline const auto&
eval(
const Eigen::Array<T, R, C>& x) {
112template <
typename T,
typename Scalar>
115 Eigen::Index dense_start = 0;
117 std::swap(start, end);
119 for (; i < x_eval.size(); ++i) {
120 if ((x_eval[i] >= start && x_eval[i] <= end)) {
125 Eigen::Index dense_size = 0;
126 for (; i < x_eval.size(); ++i) {
127 if ((x_eval[i] >= start && x_eval[i] <= end)) {
133 return std::make_pair(dense_start, dense_size);
138 = std::enable_if_t<!std::is_floating_point<std::decay_t<T>>::value>;
142 = std::enable_if_t<std::is_floating_point<std::decay_t<T>>::value>;
156 = std::enable_if_t<std::is_floating_point<std::decay_t<T>>::value
161 = std::enable_if_t<!std::is_floating_point<std::decay_t<T>>::value
164template <
typename T, require_
floating_po
int_or_complex<T>* =
nullptr>
165inline auto sin(T x) {
169template <
typename T, require_not_
floating_po
int<T>* =
nullptr>
170inline auto sin(T&& x) {
174template <
typename T, require_
floating_po
int_or_complex<T>* =
nullptr>
175inline auto cos(T x) {
179template <
typename T, require_not_
floating_po
int<T>* =
nullptr>
180inline auto cos(T&& x) {
184template <
typename T, require_
floating_po
int_or_complex<T>* =
nullptr>
185inline auto sqrt(T x) {
189template <
typename T, require_not_
floating_po
int<T>* =
nullptr>
190inline auto sqrt(T&& x) {
194template <
typename T, require_
floating_po
int_or_complex<T>* =
nullptr>
199template <
typename T, require_not_
floating_po
int<T>* =
nullptr>
200inline auto square(T&& x) {
204template <
typename T, require_
floating_po
int_or_complex<T>* =
nullptr>
205inline auto array(T x) {
209template <
typename T, require_not_
floating_po
int<T>* =
nullptr>
210inline auto array(T&& x) {
214template <
typename T, require_
floating_po
int_or_complex<T>* =
nullptr>
219template <
typename T, require_not_
floating_po
int<T>* =
nullptr>
220inline auto matrix(T&& x) {
224template <
typename T, require_
floating_po
int_or_complex<T>* =
nullptr>
226 return static_cast<T
>(0);
229template <
typename T, require_not_
floating_po
int<T>* =
nullptr>
231 return std::decay_t<typename T::PlainObject>::Zero(x.rows(), x.cols());
234template <
typename T1,
typename T2, require_
floating_po
int<T1>* =
nullptr>
235inline auto pow(T1 x, T2 y) {
236 return std::pow(x, y);
239template <
typename T1,
typename T2, require_not_
floating_po
int<T1>* =
nullptr>
240inline auto pow(T1&& x, T2 y) {
241 return x.array().pow(y);
244template <
typename T,
int R,
int C>
245inline void print(
const char* name,
const Eigen::Matrix<T, R, C>& x) {
247 std::cout << name <<
"(" << x.rows() <<
", " << x.cols() <<
")" << std::endl;
248 std::cout << x << std::endl;
252template <
typename T,
int R,
int C>
253inline void print(
const char* name,
const Eigen::Array<T, R, C>& x) {
255 std::cout << name <<
"(" << x.rows() <<
", " << x.cols() <<
")" << std::endl;
256 std::cout << x << std::endl;
262 std::enable_if_t<std::is_floating_point<std::decay_t<T>>::value
263 || std::is_integral<std::decay_t<T>>::value>* =
nullptr>
264inline void print(
const char* name, T&& x) {
266 std::cout << name <<
": " << std::setprecision(16) << x << std::endl;
272 std::enable_if_t<std::is_floating_point<std::decay_t<T>>::value
273 || std::is_integral<std::decay_t<T>>::value>* =
nullptr>
274inline void print(
const char* name,
const std::complex<T>& x) {
276 std::cout << name <<
": (" << std::setprecision(16) << x.real() <<
", "
277 << x.imag() <<
")" << std::endl;
constexpr Eigen::Index compile_size_v
std::enable_if_t<!std::is_floating_point< std::decay_t< T > >::value &&!is_complex< std::decay_t< T > >::value > require_not_floating_point_or_complex
Eigen::Matrix< Scalar, 1, -1 > row_array1d_t
Eigen::Matrix< Scalar, 1, -1 > row_vector_t
Eigen::Matrix< Scalar, -1, -1 > array2d_t
auto eval(arena_allocator< T, arena_alloc > &arena, const Expr &expr) noexcept
Eigen::Matrix< Scalar, -1, 1 > array1d_t
std::enable_if_t< std::is_floating_point< std::decay_t< T > >::value > require_floating_point
Eigen::Matrix< Scalar, -1, -1 > matrix_t
auto get_slice(T &&x_eval, Scalar start, Scalar end)
constexpr T zero_like(T x)
std::enable_if_t<!std::is_floating_point< std::decay_t< T > >::value > require_not_floating_point
auto scale(Vector &&x, Scalar x0, Scalar h)
Scales and shifts a vector of Chebyshev nodes.
std::enable_if_t< std::is_floating_point< std::decay_t< T > >::value||is_complex< std::decay_t< T > >::value > require_floating_point_or_complex
Eigen::Matrix< Scalar, -1, 1 > vector_t
void print(const char *name, const arena_matrix< T > &x)