codac 2.0.0
Loading...
Searching...
No Matches
codac2_mod.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "codac2_Interval.h"
13#include "codac2_AnalyticType.h"
15#include "codac2_arith_sub.h"
16
17namespace codac2
18{
19 struct ModOp
20 {
21 template<typename X1,typename P>
22 static std::string str(const X1& x1, const P& p)
23 {
24 return "mod(" + x1->str() + "," + p->str() + ")";
25 }
26
27 template<typename X1,typename P>
28 static std::pair<Index,Index> output_shape([[maybe_unused]] const X1& s1, [[maybe_unused]] const P& p)
29 {
30 return {1,1};
31 }
32
33 static Interval fwd(const Interval& x1, const Interval& p);
34 static ScalarType fwd_natural(const ScalarType& x1, const ScalarType& p);
35 static ScalarType fwd_centered(const ScalarType& x1, const ScalarType& p);
36 static void bwd(const Interval& y, Interval& x1, Interval& p);
37
38 static void fwd_bwd(Interval& x1, Interval& x2, double p);
39 static void fwd_bwd(Interval& x1, Interval& x2, Interval& p);
40 };
41 // Analytic operator
42 // The following function can be used to build analytic expressions.
43
44 inline ScalarExpr
45 mod(const ScalarExpr& x1, const ScalarExpr& p)
46 {
47 return { std::make_shared<AnalyticOperationExpr<ModOp,ScalarType,ScalarType,ScalarType>>(x1,p) };
48 }
49
50 // Inline functions
51
52 inline Interval ModOp::fwd(const Interval& x1, const Interval& p)
53 {
54 Interval x2, x1_(x1), p_(p);
55 ModOp::fwd_bwd(x2,x1_,p_);
56 return x2;
57 }
58
59 inline ScalarType ModOp::fwd_natural(const ScalarType& x1, const ScalarType& p)
60 {
61 return {
62 fwd(x1.a, p.a),
63 x1.def_domain && p.def_domain
64 };
65 }
66
67 inline ScalarType ModOp::fwd_centered(const ScalarType& x1, const ScalarType& p)
68 {
69 if(centered_form_not_available_for_args(x1,p))
70 return fwd_natural(x1,p);
71
72 return {
73 fwd(x1.m,p.m),
74 fwd(x1.a,p.a),
75 IntervalMatrix(0,0), // not supported yet for auto diff
76 x1.def_domain && p.def_domain
77 };
78 }
79
80 inline void ModOp::bwd(const Interval& y, Interval& x1, Interval& p)
81 {
82 Interval y_(y);
83 ModOp::fwd_bwd(y_,x1,p);
84 }
85
86 inline void ModOp::fwd_bwd(Interval& y, Interval& x1, double p) // y = x1 mod(p)
87 {
88 // The content of this function comes from the IBEX library.
89 // See ibex::Interval (IBEX lib, main author: Gilles Chabert)
90 // https://ibex-lib.readthedocs.io
91
92 assert_release(p > 0. && "Modulo needs a strictly positive period p.");
93
94 if(!(x1.diam() > p || y.diam() > p))
95 {
96 Interval r = (y-x1)/p;
97 Interval ir = integer(r);
98
99 if(ir.is_empty()) // additional protection because an empty interval is considered degenerated.
100 {
101 y.set_empty();
102 x1.set_empty();
103 }
104
105 else
106 {
107 if(ir.is_degenerated())
108 SubOp::bwd(ir*p,y,x1);
109
110 else if(ir.diam() == 1.)
111 {
112 Interval y_1 = y; Interval y_2 = y;
113 Interval x1_1 = x1; Interval x1_2 = x1;
114 SubOp::bwd(Interval(ir.lb()*p),y_1,x1_1);
115 SubOp::bwd(Interval(ir.ub()*p),y_2,x1_2);
116 y = y_1 | y_2;
117 x1 = x1_1 | x1_2;
118 }
119
120 else
121 {
122 assert_release_constexpr(false && "Modulo diameter error.");
123 }
124 }
125 }
126 }
127
128 inline void ModOp::fwd_bwd(Interval& y, Interval& x1, Interval& p) // x = y mod(p)
129 {
130 assert_release(p.is_degenerated() && "ModOp::fwd_bwd(y,x1,p) (with y and x1 intervals) not implemented yet");
131 ModOp::fwd_bwd(y, x1, p.mid());
132 }
133}
Interval class, for representing closed and connected subsets of .
Definition codac2_Interval.h:49
Definition codac2_OctaSym.h:21
Interval integer(const Interval &x)
Returns the largest integer interval included in .
Definition codac2_Interval_operations_impl.h:284
Eigen::Matrix< Interval,-1,-1 > IntervalMatrix
Alias for a dynamic-size matrix of intervals.
Definition codac2_IntervalMatrix.h:25