codac 1.5.6
Loading...
Searching...
No Matches
codac2_SlicedTube_integral_impl.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "codac2_Interval.h"
13
14namespace codac2
15{
16 template<typename T>
17 T SlicedTube<T>::integral(const Interval& t) const
18 {
19 auto partial_integ = partial_integral(t);
20
21 if(partial_integ.first.is_empty() || partial_integ.second.is_empty())
22 return this->empty_codomain();
23
24 else if(partial_integ.first.is_unbounded() || partial_integ.second.is_unbounded())
25 return this->all_reals_codomain();
26
27 else
28 return T(partial_integ.first.lb()) | partial_integ.second.ub();
29 }
30
31 template<typename T>
32 T SlicedTube<T>::integral(const Interval& t1, const Interval& t2) const
33 {
34 auto integ_t1 = partial_integral(t1);
35 auto integ_t2 = partial_integral(t2);
36
37 if(integ_t1.first.is_empty() || integ_t1.second.is_empty() ||
38 integ_t2.first.is_empty() || integ_t2.second.is_empty())
39 {
40 return this->empty_codomain();
41 }
42
43 else if(integ_t1.first.is_unbounded() || integ_t1.second.is_unbounded() ||
44 integ_t2.first.is_unbounded() || integ_t2.second.is_unbounded())
45 {
46 return this->all_reals_codomain();
47 }
48
49 else
50 {
51 auto lb = (integ_t2.first - integ_t1.first).lb();
52 auto ub = (integ_t2.second - integ_t1.second).ub();
53 return T(lb) | ub;
54 }
55 }
56
57 template<typename T>
58 std::pair<T,T> SlicedTube<T>::partial_integral(const Interval& t) const
59 {
60 //if(!t.is_subset(tdomain()->t0_tf()))
61 // return { Interval(), Interval() };
62
63 auto zero = this->all_reals_codomain();
64 zero.init(Interval(0.));
65
66 std::pair<T,T> p_integ { zero, zero };
67 auto p_integ_uncertain = p_integ;
68
69 for(const auto& si : *this)
70 {
71 if(si.t0_tf().lb() >= t.ub())
72 break;
73
74 if(si.codomain().is_empty())
75 {
76 auto e = this->empty_codomain();
77 return { e, e };
78 }
79
80 if(si.codomain().is_unbounded())
81 {
82 auto u = this->all_reals_codomain();
83 return { u, u };
84 }
85
86 // From t0 to tlb
87
88 Interval intv_t = si.t0_tf() & Interval(tdomain()->t0_tf().lb(), t.lb());
89 if(!intv_t.is_empty())
90 {
91 p_integ.first += intv_t.diam() * si.codomain().lb();
92 p_integ.second += intv_t.diam() * si.codomain().ub();
93 p_integ_uncertain = p_integ;
94
95 if(intv_t.ub() == t.ub())
96 return p_integ; // end of the integral evaluation
97 }
98
99 // From tlb to tub
100
101 intv_t = si.t0_tf() & t;
102 if(!intv_t.is_empty())
103 {
104 auto p_integ_temp = p_integ_uncertain;
105 p_integ_uncertain.first += Interval(0., intv_t.diam()) * si.codomain().lb();
106 p_integ_uncertain.second += Interval(0., intv_t.diam()) * si.codomain().ub();
107
108 p_integ.first |= p_integ_uncertain.first;
109 p_integ.second |= p_integ_uncertain.second;
110
111 p_integ_uncertain.first = p_integ_temp.first + intv_t.diam() * si.codomain().lb();
112 p_integ_uncertain.second = p_integ_temp.second + intv_t.diam() * si.codomain().ub();
113 }
114 }
115
116 return p_integ;
117 }
118
119 template<typename T>
120 std::pair<T,T> SlicedTube<T>::partial_integral(const Interval& t1, const Interval& t2) const
121 {
122 auto integ_t1 = partial_integral(t1);
123 auto integ_t2 = partial_integral(t2);
124 return {
125 integ_t2.first - integ_t1.first,
126 integ_t2.second - integ_t1.second
127 };
128 }
129}
Interval class, for representing closed and connected subsets of .
Definition codac2_Interval.h:62
double ub() const
Returns the upper bound of this.
Definition codac2_Interval_impl.h:113
double lb() const
Returns the lower bound of this.
Definition codac2_Interval_impl.h:108