21#include "codac2_vec.h"
35 inline EvalMode operator&(EvalMode a, EvalMode b)
36 {
return static_cast<EvalMode
>(
static_cast<int>(a) &
static_cast<int>(b)); }
38 inline EvalMode operator|(EvalMode a, EvalMode b)
39 {
return static_cast<EvalMode
>(
static_cast<int>(a) |
static_cast<int>(b)); }
41 struct ScalarExprList :
public AnalyticExprWrapper<VectorType>
44 template<
typename... S>
45 requires (std::is_same_v<typename ExprType<S>::Type,ScalarType> && ...)
46 ScalarExprList(
const S&... y)
47 : AnalyticExprWrapper<VectorType>(vec(y...))
58 requires std::is_base_of_v<AnalyticTypeBase,T>
59 class AnalyticFunction :
public FunctionBase<AnalyticExpr<T>>
63 AnalyticFunction(
const FunctionArgsList&
args,
const ScalarExprList& y)
64 requires(std::is_same_v<T,VectorType>)
67 assert_release(y->belongs_to_args_list(this->args()) &&
68 "Invalid argument: variable not present in input arguments");
72 AnalyticFunction(
const FunctionArgsList&
args,
const AnalyticExprWrapper<T>& y)
75 assert_release(y->belongs_to_args_list(this->args()) &&
76 "Invalid argument: variable not present in input arguments");
80 AnalyticFunction(
const AnalyticFunction<T>& f)
84 template<
typename... X>
85 AnalyticExprWrapper<T> operator()(
const X&... x)
const
90 template<
typename... Args>
91 auto real_eval(
const Args&... x)
const
93 return eval(x...).mid();
96 template<
typename... Args>
97 typename T::Domain eval(
const EvalMode& m,
const Args&... x)
const
99 check_valid_inputs(x...);
103 case EvalMode::NATURAL:
105 return eval_<true>(x...).a;
108 case EvalMode::CENTERED:
110 auto x_ = eval_<false>(x...);
112 assert(x_.da.rows() == x_.a.size() && x_.da.cols() == flatten_x.size());
114 if constexpr(std::is_same_v<T,ScalarType>)
115 return x_.m + (x_.da*(flatten_x-flatten_x.mid()))[0];
117 else if constexpr(std::is_same_v<T,VectorType>)
118 return x_.m + (x_.da*(flatten_x-flatten_x.mid())).col(0);
122 static_assert(std::is_same_v<T,MatrixType>);
123 return x_.m + (x_.da*(flatten_x-flatten_x.mid()))
124 .reshaped(x_.m.rows(), x_.m.cols());
128 case EvalMode::DEFAULT:
131 auto x_ = eval_<false>(x...);
136 return eval(EvalMode::NATURAL, x...);
142 if constexpr(std::is_same_v<T,ScalarType>)
143 return x_.a & (x_.m + (x_.da*(flatten_x-flatten_x.mid()))[0]);
145 else if constexpr(std::is_same_v<T,VectorType>)
147 assert(x_.da.rows() == x_.a.size() && x_.da.cols() == flatten_x.size());
148 return x_.a & (x_.m + (x_.da*(flatten_x-flatten_x.mid())).col(0));
153 static_assert(std::is_same_v<T,MatrixType>);
154 assert(x_.da.rows() == x_.a.size() && x_.da.cols() == flatten_x.size());
155 return x_.a & (x_.m +(x_.da*(flatten_x-flatten_x.mid()))
156 .reshaped(x_.m.rows(),x_.m.cols()));
163 template<
typename... Args>
164 auto diff(
const Args&... x)
const
166 check_valid_inputs(x...);
167 return eval_<false>(x...).da;
170 template<
typename... Args>
171 typename T::Domain eval(
const Args&... x)
const
173 return eval(EvalMode::NATURAL | EvalMode::CENTERED, x...);
176 template<
typename... Args>
177 auto traj_eval(
const SampledTraj<Args>&... x)
const
179 SampledTraj<typename T::Scalar> y;
180 for(
const auto& [ti,xi] : std::get<0>(std::tie(x...)))
181 y.set(this->real_eval(x(ti)...),ti);
185 template<
typename... Args>
186 auto tube_eval(
const SlicedTube<Args>&... x)
const
188 auto tdomain = std::get<0>(std::tie(x...)).tdomain();
190 SlicedTube<typename T::Domain> y(
191 tdomain, (
typename T::Domain)(this->output_size())
194 for(
auto it = tdomain->begin() ; it != tdomain->end() ; it++)
195 y.slice(it)->codomain() = this->eval(x.slice(it)->codomain()...);
200 template<
typename... Args>
201 requires std::is_same_v<VectorType,T> && ((!std::is_same_v<MatrixType,typename ExprType<Args>::Type>) && ...)
202 Parallelepiped parallelepiped_eval(const Args&... x)
const
204 this->check_valid_inputs(x...);
205 assert_release(this->
input_size() < this->output_size() &&
206 "Parallelepiped evaluation requires more outputs than inputs.");
208 "Parallelepiped evaluation requires at least one input.");
213 Matrix A = this->diff(((
typename Wrapper<Args>::Domain)(x)).
mid()...).mid();
216 double rho =
error_peibos(Y, z, this->diff(x...), A, cart_prod(x...));
221 return Parallelepiped(z, A_inf);
224 Index output_size()
const
226 if constexpr(std::is_same_v<T,ScalarType>)
230 std::pair<Index,Index> oshape = output_shape();
231 return oshape.first * oshape.second;
235 std::pair<Index,Index> output_shape()
const
237 if constexpr(std::is_same_v<T,ScalarType>)
239 else return this->
expr()->output_shape();
242 friend std::ostream& operator<<(std::ostream& os, [[maybe_unused]]
const AnalyticFunction<T>& f)
245 for(
size_t i = 0 ; i < f.args().size() ; i++)
246 os << (i!=0 ?
"," :
"") << f.args()[i]->name();
247 os <<
") ↦ " << f.expr()->str();
259 template<
typename... Args>
260 void fill_from_args(ValuesMap& v,
const Args&... x)
const
263 (add_value_to_arg_map(v, x, i++), ...);
266 template<
typename... Args>
267 void intersect_from_args(
const ValuesMap& v, Args&... x)
const
270 (intersect_value_from_arg_map(v, x, i++), ...);
276 void add_value_to_arg_map(ValuesMap& v,
const D& x, Index i)
const
278 assert(i >= 0 && i < (Index)this->
args().size());
279 assert_release(size_of(x) == this->
args()[i]->size() &&
"provided arguments do not match function inputs");
281 using D_TYPE =
typename ExprType<D>::Type;
286 for(Index j = 0 ; j < i ; j++)
287 p += this->
args()[j]->size();
289 for(Index k = p ; k < p+size_of(x) ; k++)
292 v[this->
args()[i]->unique_id()] =
293 std::make_shared<D_TYPE>(
typename D_TYPE::Domain(x).
mid(), x, d,
true);
297 void intersect_value_from_arg_map(
const ValuesMap& v, D& x, Index i)
const
299 assert(v.find(this->args()[i]->unique_id()) != v.end() &&
"argument cannot be found");
300 x &= std::dynamic_pointer_cast<typename ExprType<D>::Type>(v.at(this->
args()[i]->unique_id()))->a;
303 template<
bool NATURAL_EVAL,
typename... Args>
304 auto eval_(
const Args&... x)
const
308 if constexpr(
sizeof...(Args) == 0)
309 return this->
expr()->fwd_eval(v, 0, NATURAL_EVAL);
313 fill_from_args(v, x...);
314 return this->
expr()->fwd_eval(v, cart_prod(x...).size(), NATURAL_EVAL);
318 template<
typename... Args>
319 void check_valid_inputs(
const Args&... x)
const
321 [[maybe_unused]] Index n = 0;
322 ((n += size_of(x)), ...);
324 assert_release(this->
_args.total_size() == n &&
325 "Invalid arguments: wrong number of input arguments");
328 inline void update_var_names()
330 for(
const auto& v : this->
_args)
332 this->
_y->replace_arg(v->unique_id(), std::dynamic_pointer_cast<ExprBase>(v));
336 AnalyticFunction(
const FunctionArgsList&, std::initializer_list<ScalarExpr>) ->
337 AnalyticFunction<VectorType>;
341 AnalyticFunction<typename ExprType<T>::Type>;
A container class to manage a collection of function arguments.
Definition codac2_FunctionArgsList.h:25
A base class for functions (either analytic functions, or set functions).
Definition codac2_FunctionBase.h:41
const FunctionArgsList & args() const
Definition codac2_FunctionBase.h:93
const FunctionArgsList _args
Definition codac2_FunctionBase.h:218
FunctionBase(const std::vector< std::reference_wrapper< VarBase > > &args, const std::shared_ptr< AnalyticExpr< T > > &y)
Definition codac2_FunctionBase.h:52
Index input_size() const
Definition codac2_FunctionBase.h:165
const std::shared_ptr< AnalyticExpr< T > > _y
Definition codac2_FunctionBase.h:217
const std::shared_ptr< AnalyticExpr< T > > & expr() const
Definition codac2_FunctionBase.h:113
auto mid() const
Returns a matrix containing the midpoints of each interval element.
Definition codac2_MatrixBase_addons_IntervalMatrixBase.h:117
Definition codac2_OctaSym.h:21
Eigen::Matrix< double,-1, 1 > Vector
Alias for a dynamically-sized column vector of doubles.
Definition codac2_Vector.h:24
Matrix inflate_flat_parallelepiped(const Matrix &A, const Vector &e_vec, double rho)
Inflate the flat parallelepiped by .
double error_peibos(const IntervalVector &Y, const Vector &z, const IntervalMatrix &Jf, const Matrix &A, const IntervalVector &X)
Compute the error term for the parallelepiped inclusion. The error is later used to inflate the flat ...
Eigen::Matrix< Interval,-1, 1 > IntervalVector
Alias for a dynamic-size column vector of intervals.
Definition codac2_IntervalVector.h:25
Eigen::Matrix< double,-1,-1 > Matrix
Alias for a dynamic-size matrix of doubles.
Definition codac2_Matrix.h:26
Eigen::Matrix< Interval,-1,-1 > IntervalMatrix
Alias for a dynamic-size matrix of intervals.
Definition codac2_IntervalMatrix.h:25