codac 1.5.6
Loading...
Searching...
No Matches
codac2_atan2.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_atan2.h"
16#include "codac2_arith_div.h"
17
18namespace codac2
19{
20 struct Atan2Op
21 {
22 static Interval fwd(const Interval& x1, const Interval& x2);
23 static ScalarType fwd_natural(const ScalarType& x1, const ScalarType& x2);
24 static ScalarType fwd_centered(const ScalarType& x1, const ScalarType& x2);
25 static void bwd(const Interval& y, Interval& x1, Interval& x2);
26 };
27
28 // Analytic operator
29 // The following function can be used to build analytic expressions.
30
31 inline ScalarExpr
32 atan2(const ScalarExpr& x1, const ScalarExpr& x2)
33 {
34 return { std::make_shared<AnalyticOperationExpr<Atan2Op,ScalarType,ScalarType,ScalarType>>(x1,x2) };
35 }
36
37 // Inline functions
38
39 inline Interval Atan2Op::fwd(const Interval& x1, const Interval& x2)
40 {
41 return atan2(x1,x2);
42 }
43
44 inline ScalarType Atan2Op::fwd_natural(const ScalarType& x1, const ScalarType& x2)
45 {
46 return {
47 fwd(x1.a, x2.a),
48 x1.def_domain && x2.def_domain
49 && !(x1.a == 0. && x2.a == 0.) // def domain of the derivative of atan2
50 };
51 }
52
53 inline ScalarType Atan2Op::fwd_centered(const ScalarType& x1, const ScalarType& x2)
54 {
55 if(centered_form_not_available_for_args(x1,x2))
56 return fwd_natural(x1,x2);
57
58 assert(x1.da.rows() == 1);
59 assert(x1.da.rows() == x2.da.rows() && x1.da.cols() == x2.da.cols());
60
61 IntervalMatrix d(1,x1.da.cols());
62 for(Index i = 0 ; i < d.size() ; i++)
63 d(0,i) = (-x1.a*x2.da(0,i)/(sqr(x2.a)+sqr(x1.a)))+(x2.a*x1.da(0,i)/(sqr(x2.a)+sqr(x1.a)));
64
65 return {
66 fwd(x1.m, x2.m),
67 fwd(x1.a, x2.a),
68 d,
69 x1.def_domain && x2.def_domain
70 && !(x1.a == 0. && x2.a == 0.) // def domain of the derivative of atan2
71 };
72 }
73
74 inline void Atan2Op::bwd(const Interval& y, Interval& x1, Interval& x2)
75 {
76 // The content of this function comes from the IBEX library.
77 // See ibex::Interval (IBEX lib, main author: Gilles Chabert)
78 // https://ibex-lib.readthedocs.io
79
80 // Probably not the most efficient implementation ever...
81
82 // half-plane x2>0
83 Interval y_x2pos = y & Interval(-1,1)*Interval::half_pi();
84 // upper left quadrant
85 Interval y_x2neg_x1pos = y & (Interval::half_pi() | Interval::pi());
86 // lower left quadrant
87 Interval y_x2neg_x1neg = y & -(Interval::half_pi() | Interval::pi());
88
89 Interval xres = Interval::empty();
90 Interval yres = Interval::empty();
91
92 if(!y_x2pos.is_empty())
93 {
94 Interval xpos = x2 & Interval(0,oo);
95 Interval yall = x1;
96
97 if(y_x2neg_x1pos.is_empty() || y_x2neg_x1neg.is_empty())
98 {
99 Interval z = yall/xpos;
100 AtanOp::bwd(y_x2pos,z);
101 DivOp::bwd(z,yall,xpos);
102 } // Otherwise, all is valid (useless to contract)
103
104 xres |= xpos;
105 yres |= yall;
106
107 // Because atan is not defined for pi/2 and -pi/2
108 if(y_x2pos.lb() >= Interval::half_pi().lb())
109 {
110 xres |= (x2 & Interval::zero());
111 yres |= (x1 & Interval(0,oo));
112 }
113 else if(y_x2pos.ub() <= -Interval::half_pi().lb())
114 {
115 xres |= (x2 & Interval::zero());
116 yres |= (x1 & Interval(-oo,0));
117 }
118 }
119
120 if(!y_x2neg_x1pos.is_empty())
121 {
122 Interval xneg = x2 & Interval(-oo,0);
123 Interval ypos = x1 & Interval(0,oo);
124 Interval z = ypos/xneg;
125 AtanOp::bwd(y_x2neg_x1pos - Interval::pi(),z);
126 DivOp::bwd(z,ypos,xneg);
127 xres |= xneg;
128 yres |= ypos;
129 }
130
131 if(!y_x2neg_x1neg.is_empty())
132 {
133 Interval xneg = x2 & Interval(-oo,0);
134 Interval yneg = x1 & Interval(-oo,0);
135 Interval z = yneg/xneg;
136 AtanOp::bwd(y_x2neg_x1neg + Interval::pi(),z);
137 DivOp::bwd(z,yneg,xneg);
138 xres |= xneg;
139 yres |= yneg;
140 }
141
142 x2 = xres;
143 x1 = yres;
144 }
145}
Interval class, for representing closed and connected subsets of .
Definition codac2_Interval.h:62
static Interval pi()
Provides an interval for .
Definition codac2_Interval_impl.h:555
static Interval zero()
Provides an interval for .
Definition codac2_Interval_impl.h:540
double lb() const
Returns the lower bound of this.
Definition codac2_Interval_impl.h:102
static Interval empty()
Provides an empty interval.
Definition codac2_Interval_impl.h:535
static Interval half_pi()
Provides an interval for .
Definition codac2_Interval_impl.h:550
Interval atan2(const Interval &y, const Interval &x)
Returns .
Definition codac2_Interval_operations_impl.h:140
Interval sqr(const Interval &x)
Returns .
Definition codac2_Interval_operations_impl.h:21