codac 1.5.6
Loading...
Searching...
No Matches
codac2_chi.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "codac2_Interval.h"
13#include "codac2_AnalyticType.h"
16
17namespace codac2
18{
19 // chi([x1],[x2],[x3]) = [x2] if (x1^+)<=0, [x3] if (x1^-)>0, hull([x2],[x3]) else
20
21 struct ChiOp
22 {
23 template<typename X1,typename X2,typename X3>
24 static std::string str(const X1& x1, const X2& x2, const X3& x3)
25 {
26 return "χ(" + x1->str() + "," + x2->str() + "," + x3->str() + ")";
27 }
28
29 template<typename X1, typename X2, typename X3>
30 static std::pair<Index,Index> output_shape([[maybe_unused]] const X1& s1, const X2& s2, [[maybe_unused]] const X3& s3)
31 {
32 auto shape2 = s2->output_shape();
33 assert(shape2 == s3->output_shape());
34 return shape2;
35 }
36
37 template<typename T>
38 static inline T fwd(const Interval& x1, const T& x2, const T& x3)
39 {
40 // Copy of chi from codac2_Interval_operations_impl.h
41 if(x1.ub() <= 0)
42 return x2;
43 else if(x1.lb() > 0)
44 return x3;
45 else
46 return x2 | x3;
47 }
48
49 template<typename T>
50 static inline T fwd_natural(const ScalarType& x1, const T& x2, const T& x3)
51 {
52 return {
53 fwd(x1.a,x2.a,x3.a),
54 x1.def_domain
55 && ((x1.a.lb()>0.0) ? x2.def_domain : true)
56 && ((x1.a.ub()<=0.0) ? x3.def_domain : true)
57 };
58 }
59
60 template<typename T>
61 static inline T fwd_centered(const ScalarType& x1, const T& x2, const T& x3)
62 {
63 if(centered_form_not_available_for_args(x1,x2,x3))
64 return fwd_natural(x1,x2,x3);
65
66 assert(x2.da.rows() == x3.da.rows());
67
68 return {
69 fwd(x1.m,x2.m,x3.m),
70 fwd(x1.a,x2.a,x3.a),
71 (x1.a.lb()>0 ? x3.da : ((x1.a.ub()<=0) ? x2.da : (x2.da | x3.da))),
72 x1.def_domain
73 && ((x1.a.lb()>0.0) ? x2.def_domain : true)
74 && ((x1.a.ub()<=0.0) ? x3.def_domain : true)
75 };
76 }
77
78 template<typename T>
79 static inline void bwd(const T& y, Interval& x1, T& x2, T& x3)
80 {
81 // The content of this function comes from the IBEX library.
82 // See ibex::Interval (IBEX lib, main author: Gilles Chabert)
83 // https://ibex-lib.readthedocs.io
84 // Some updates have been proposed by Damien Massé.
85
86 if(x1.ub() <= 0)
87 {
88 if((x2 &= y).is_empty())
89 {
90 x1.set_empty();
91 x3.set_empty();
92 }
93 }
94
95 else if(x1.lb() > 0)
96 {
97 if((x3 &= y).is_empty())
98 {
99 x1.set_empty();
100 x2.set_empty();
101 }
102 }
103
104 if(y.is_disjoint(x2))
105 {
106 if((x1 &= Interval(0,oo)).is_empty())
107 {
108 x2.set_empty();
109 x3.set_empty();
110 }
111
112 if((x3 &= y).is_empty())
113 {
114 x1.set_empty();
115 x2.set_empty();
116 }
117 }
118
119 if(y.is_disjoint(x3))
120 {
121 if((x1 &= Interval(-oo,0)).is_empty())
122 {
123 x2.set_empty();
124 x3.set_empty();
125 }
126
127 if((x2 &= y).is_empty())
128 {
129 x1.set_empty();
130 x3.set_empty();
131 }
132 }
133 }
134 };
135
136 // Analytic operator
137 // The following function can be used to build analytic expressions.
138
139 template<typename T2,typename T3,typename T=ExprType<T2>::Type>
140 inline AnalyticExprWrapper<T>
141 chi(const ScalarExpr& x1, const T2& x2, const T3& x3)
142 {
143 return { std::make_shared<AnalyticOperationExpr<ChiOp,T,ScalarType,T,T>>(
144 x1,(AnalyticExprWrapper<T>)x2,(AnalyticExprWrapper<T>)x3) };
145 }
146
147}
Interval chi(const Interval &x, const Interval &y, const Interval &z)
Return if , if , else.
Definition codac2_Interval_operations_impl.h:299