codac 2.0.0
Loading...
Searching...
No Matches
codac2_arith_div.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "codac2_Interval.h"
15#include "codac2_AnalyticType.h"
17#include "codac2_arith_mul.h"
18
19namespace codac2
20{
21 struct DivOp
22 {
23 template<typename X1,typename X2>
24 static std::string str(const X1& x1, const X2& x2)
25 {
26 return x1->str(!x1->is_str_leaf()) + "/" + x2->str(!x2->is_str_leaf());
27 }
28
29 template<typename X1,typename X2>
30 static std::pair<Index,Index> output_shape(const X1& s1, const X2& s2)
31 {
32 auto shape1=s1->output_shape();
33 auto shape2=s2->output_shape();
34 assert_release(shape2.first == 1 && shape2.second == 1);
35 return shape1;
36 }
37
38 static Interval fwd(const Interval& x1, const Interval& x2);
39 static ScalarType fwd_natural(const ScalarType& x1, const ScalarType& x2);
40 static ScalarType fwd_centered(const ScalarType& x1, const ScalarType& x2);
41 static void bwd(const Interval& y, Interval& x1, Interval& x2);
42
43 static IntervalVector fwd(const IntervalVector& x1, const Interval& x2);
44 static VectorType fwd_natural(const VectorType& x1, const ScalarType& x2);
45 static VectorType fwd_centered(const VectorType& x1, const ScalarType& x2);
46 static void bwd(const IntervalVector& y, IntervalVector& x1, Interval& x2);
47
48 static IntervalMatrix fwd(const IntervalMatrix& x1, const Interval& x2);
49 static MatrixType fwd_natural(const MatrixType& x1, const ScalarType& x2);
50 static MatrixType fwd_centered(const MatrixType& x1, const ScalarType& x2);
51 static void bwd(const IntervalMatrix& y, IntervalMatrix& x1, Interval& x2);
52 };
53
54 // operator/
55 // The following functions can be used to build analytic expressions.
56
57 inline ScalarExpr
58 operator/(const ScalarExpr& x1, const ScalarExpr& x2)
59 {
60 return { std::make_shared<AnalyticOperationExpr<DivOp,ScalarType,ScalarType,ScalarType>>(x1,x2) };
61 }
62
63 inline VectorExpr
64 operator/(const VectorExpr& x1, const ScalarExpr& x2)
65 {
66 return { std::make_shared<AnalyticOperationExpr<DivOp,VectorType,VectorType,ScalarType>>(x1,x2) };
67 }
68
69 inline MatrixExpr
70 operator/(const MatrixExpr& x1, const ScalarExpr& x2)
71 {
72 return { std::make_shared<AnalyticOperationExpr<DivOp,MatrixType,MatrixType,ScalarType>>(x1,x2) };
73 }
74
75 // Inline functions
76
77 inline Interval DivOp::fwd(const Interval& x1, const Interval& x2)
78 {
79 return x1 / x2;
80 }
81
82 inline ScalarType DivOp::fwd_natural(const ScalarType& x1, const ScalarType& x2)
83 {
84 return {
85 fwd(x1.a, x2.a),
86 x1.def_domain && x2.def_domain && x2.a != 0. // def domain of the derivative of div
87 };
88 }
89
90 inline ScalarType DivOp::fwd_centered(const ScalarType& x1, const ScalarType& x2)
91 {
92 if(centered_form_not_available_for_args(x1,x2))
93 return fwd_natural(x1,x2);
94
95 assert(x1.da.size() == x2.da.size());
96
97 IntervalMatrix d(1,x1.da.size());
98 for(Index i = 0 ; i < d.size() ; i++)
99 d(0,i) = (x1.da(0,i)*x2.a-x1.a*x2.da(0,i))/sqr(x2.a);
100
101 return {
102 fwd(x1.m, x2.m),
103 fwd(x1.a, x2.a),
104 d,
105 x1.def_domain && x2.def_domain && x2.a != 0. // def domain of the derivative of div
106 };
107 }
108
109 inline void DivOp::bwd(const Interval& y, Interval& x1, Interval& x2)
110 {
111 if((x1 &= y*x2).is_empty())
112 x2.set_empty();
113
114 else
115 {
116 Interval tmp = y;
117 MulOp::bwd(x1, tmp, x2);
118 if(x2.is_empty())
119 x1.set_empty();
120 }
121 }
122
123 inline IntervalVector DivOp::fwd(const IntervalVector& x1, const Interval& x2)
124 {
125 return x1 / x2;
126 }
127
128 inline VectorType DivOp::fwd_natural(const VectorType& x1, const ScalarType& x2)
129 {
130 return {
131 fwd(x1.a, x2.a),
132 x1.def_domain && x2.def_domain && x2.a != 0. // def domain of the derivative of div
133 };
134 }
135
136 inline VectorType DivOp::fwd_centered(const VectorType& x1, const ScalarType& x2)
137 {
138 if(centered_form_not_available_for_args(x1,x2))
139 return fwd_natural(x1,x2);
140
141 assert(x2.da.rows() == 1);
142 assert(x1.da.cols() == x2.da.cols());
143
144 IntervalMatrix d(x1.da.rows(),x1.da.cols());
145 for(Index j = 0 ; j < d.cols() ; j++)
146 for(Index i = 0 ; i < d.rows() ; i++)
147 d(i,j) = x1.da(i,j)/x2.a - x1.a[i]*x2.da(0,j)/sqr(x2.a);
148
149 return {
150 fwd(x1.m, x2.m),
151 fwd(x1.a, x2.a),
152 d,
153 x1.def_domain && x2.def_domain && x2.a != 0. // def domain of the derivative of div
154 };
155 }
156
157 inline void DivOp::bwd(const IntervalVector& y, IntervalVector& x1, Interval& x2)
158 {
159 assert(x1.size() == y.size());
160 for(Index i = 0 ; i < x1.size() ; i++)
161 DivOp::bwd(y[i], x1[i], x2);
162 }
163
164 inline IntervalMatrix DivOp::fwd(const IntervalMatrix& x1, const Interval& x2)
165 {
166 return x1 / x2;
167 }
168
169 inline MatrixType DivOp::fwd_natural(const MatrixType& x1, const ScalarType& x2)
170 {
171 return {
172 fwd(x1.a, x2.a),
173 x1.def_domain && x2.def_domain && x2.a != 0. // def domain of the derivative of div
174 };
175 }
176
177 inline MatrixType DivOp::fwd_centered(const MatrixType& x1, const ScalarType& x2)
178 {
179 if(centered_form_not_available_for_args(x1,x2))
180 return fwd_natural(x1,x2);
181
182 assert(x2.da.rows() == 1);
183 assert(x1.da.cols() == x2.da.cols());
184
185 IntervalMatrix d(x1.da.rows(),x1.da.cols());
186 for(Index j = 0 ; j < d.cols() ; j++)
187 for(Index i = 0 ; i < d.rows() ; i++)
188 d(i,j) = x1.da(i,j)/x2.a -
189 x1.a.reshaped<Eigen::ColMajor>()[i]*x2.da(0,j)/sqr(x2.a);
190
191 return {
192 fwd(x1.m, x2.m),
193 fwd(x1.a, x2.a),
194 d,
195 x1.def_domain && x2.def_domain && x2.a != 0. // def domain of the derivative of div
196 };
197 }
198
199 inline void DivOp::bwd(const IntervalMatrix& y, IntervalMatrix& x1, Interval& x2)
200 {
201 assert(x1.cols() == y.cols() && x1.rows() == y.rows());
202 for(Index j = 0 ; j < x1.cols() ; j++)
203 for(Index i = 0 ; i < x1.rows() ; i++)
204 DivOp::bwd(y(i,j), x1(i,j), x2);
205 }
206}
Interval class, for representing closed and connected subsets of .
Definition codac2_Interval.h:62
Interval operator/(const Interval &x, double y)
Returns with .
Definition codac2_Interval_impl.h:435
Interval sqr(const Interval &x)
Returns .
Definition codac2_Interval_operations_impl.h:21