main page
modules
namespaces
classes
files
Gecode home
Generated on Tue Jan 28 2020 00:00:00 for Gecode by
doxygen
1.8.17
gecode
float
trigonometric
tanatan.hpp
Go to the documentation of this file.
1
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
/*
3
* Main authors:
4
* Vincent Barichard <Vincent.Barichard@univ-angers.fr>
5
*
6
* Copyright:
7
* Vincent Barichard, 2012
8
*
9
* Last modified:
10
* $Date: 2016-04-19 17:19:45 +0200 (Tue, 19 Apr 2016) $ by $Author: schulte $
11
* $Revision: 14967 $
12
*
13
* This file is part of Gecode, the generic constraint
14
* development environment:
15
* http://www.gecode.org
16
*
17
* Permission is hereby granted, free of charge, to any person obtaining
18
* a copy of this software and associated documentation files (the
19
* "Software"), to deal in the Software without restriction, including
20
* without limitation the rights to use, copy, modify, merge, publish,
21
* distribute, sublicense, and/or sell copies of the Software, and to
22
* permit persons to whom the Software is furnished to do so, subject to
23
* the following conditions:
24
*
25
* The above copyright notice and this permission notice shall be
26
* included in all copies or substantial portions of the Software.
27
*
28
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
*
36
*/
37
38
namespace
Gecode
{
namespace
Float {
namespace
Trigonometric {
39
/*
40
* ATan projection function
41
*
42
*/
43
template
<
class
V>
44
void
45
aTanProject
(
Rounding
&
r
,
const
V& aTanIv,
FloatNum
& iv_min,
FloatNum
& iv_max,
int
& n_min,
int
& n_max) {
46
#define I0__PI_2I FloatVal(0,pi_half_upper())
47
#define POS(X) ((I0__PI_2I.in(X))?0:1)
48
#define ATANINF_DOWN r.atan_down(aTanIv.min())
49
#define ATANSUP_UP r.atan_up(aTanIv.max())
50
51
// 0 <=> in [0;PI/2]
52
// 1 <=> in [PI/2;PI]
53
switch
(
POS
(iv_min) )
54
{
55
case
0:
56
if
(
r
.tan_down(iv_min) > aTanIv.max()) { n_min++; iv_min =
ATANINF_DOWN
; }
57
else
if
(
r
.tan_up(iv_min) < aTanIv.min()) { iv_min =
ATANINF_DOWN
; }
58
break
;
59
case
1:
60
if
(
r
.tan_down(iv_min) > aTanIv.max()) { n_min+=2; iv_min =
ATANINF_DOWN
; }
61
else
if
(
r
.tan_up(iv_min) < aTanIv.min()) { n_min++; iv_min =
ATANINF_DOWN
; }
62
break
;
63
default
:
64
GECODE_NEVER
;
65
break
;
66
}
67
68
// 0 <=> in [0;PI/2]
69
// 1 <=> in [PI/2;PI]
70
switch
(
POS
(iv_max) )
71
{
72
case
0:
73
if
(
r
.tan_down(iv_max) > aTanIv.max()) { iv_max =
ATANSUP_UP
; }
74
else
if
(
r
.tan_up(iv_max) < aTanIv.min()) { n_max--; iv_max =
ATANSUP_UP
; }
75
break
;
76
case
1:
77
if
(
r
.tan_down(iv_max) > aTanIv.max()) { n_max++; iv_max =
ATANSUP_UP
; }
78
else
if
(
r
.tan_up(iv_max) < aTanIv.min()) { iv_max =
ATANSUP_UP
; }
79
break
;
80
default
:
81
GECODE_NEVER
;
82
break
;
83
}
84
#undef ATANINF_DOWN
85
#undef ATANSUP_UP
86
#undef POS
87
#undef I0__PI_2I
88
}
89
90
/*
91
* Bounds consistent tangent operator
92
*
93
*/
94
95
template
<
class
A,
class
B>
96
forceinline
97
Tan<A,B>::Tan
(
Home
home, A x0, B x1)
98
:
MixBinaryPropagator
<A,
PC_FLOAT_BND
,B,
PC_FLOAT_BND
>(home,x0,x1) {}
99
100
template
<
class
A,
class
B>
101
ExecStatus
102
Tan<A,B>::post
(
Home
home, A x0, B x1) {
103
if
(
same
(x0,x1)) {
104
#define I0__PI_2I FloatVal(0,pi_half_upper())
105
if
(
I0__PI_2I
.in(x0.max()))
GECODE_ME_CHECK
(x0.lq(home,0));
106
if
(
I0__PI_2I
.in(-x0.min()))
GECODE_ME_CHECK
(x0.gq(home,0));
107
#undef I0__PI_2I
108
}
109
110
(void)
new
(home)
Tan<A,B>
(home,x0,x1);
111
return
ES_OK
;
112
}
113
114
template
<
class
A,
class
B>
115
forceinline
116
Tan<A,B>::Tan
(
Space
& home,
bool
share,
Tan<A,B>
&
p
)
117
:
MixBinaryPropagator
<A,
PC_FLOAT_BND
,B,
PC_FLOAT_BND
>(home,share,
p
) {}
118
119
template
<
class
A,
class
B>
120
Actor
*
121
Tan<A,B>::copy
(
Space
& home,
bool
share) {
122
return
new
(home)
Tan<A,B>
(home,share,*
this
);
123
}
124
125
template
<
class
A,
class
B>
126
ExecStatus
127
Tan<A,B>::propagate
(
Space
& home,
const
ModEventDelta
&) {
128
Rounding
r
;
129
int
n_min =
static_cast<
int
>
(
r
.div_up(x0.min() +
pi_half_upper
(),
pi_upper
()));
130
int
n_max =
static_cast<
int
>
(
r
.div_up(x0.max() +
pi_half_upper
(),
pi_upper
()));
131
132
if
(
same
(x0,x1)) {
133
#define I0__PI_2I FloatVal(0,pi_half_upper())
134
if
(
I0__PI_2I
.in(x0.max()))
GECODE_ME_CHECK
(x0.lq(home,0));
135
if
(
I0__PI_2I
.in(-x0.min()))
GECODE_ME_CHECK
(x0.gq(home,0));
136
#undef I0__PI_2I
137
138
n_min =
static_cast<
int
>
(
r
.div_up(x0.min(),
pi_upper
()));
139
n_max =
static_cast<
int
>
(
r
.div_up(x0.max(),
pi_upper
()));
140
141
FloatNum
x0_min;
142
FloatNum
x0_max;
143
FloatNum
t
= x0.min();
144
do
{
145
x0_min =
t
;
146
if
(
r
.tan_down(x0_min) > x0_min) n_min++;
147
t
=
r
.add_down(
r
.mul_up(n_min,
pi_upper
()),
r
.tan_down(x0_min));
148
}
while
(
t
> x0_min);
149
t
=
r
.sub_down(
r
.mul_up(2*n_max,
pi_upper
()),x0.max());
150
do
{
151
x0_max =
t
;
152
if
(
r
.tan_down(x0_max) < x0_max) n_max--;
153
t
=
r
.add_up(
r
.mul_up(n_max,
pi_upper
()),
r
.tan_up(x0_max));
154
}
while
(
t
> x0_max);
155
x0_max =
r
.sub_up(
r
.mul_up(2*n_max,
pi_upper
()),x0_max);
156
157
if
(x0_min > x0_max)
return
ES_FAILED
;
158
GECODE_ME_CHECK
(x0.eq(home,
FloatVal
(x0_min,x0_max)));
159
}
else
{
160
GECODE_ME_CHECK
(x1.eq(home,
tan
(x0.val())));
161
n_min =
static_cast<
int
>
(
r
.div_up(x0.min(),
pi_upper
()));
162
n_max =
static_cast<
int
>
(
r
.div_up(x0.max(),
pi_upper
()));
163
if
(x0.min() < 0) n_min--;
164
if
(x0.max() < 0) n_max--;
165
FloatNum
iv_min =
r
.sub_down(x0.min(),
r
.mul_down(n_min,
pi_upper
()));
166
FloatNum
iv_max =
r
.sub_up (x0.max(),
r
.mul_down(n_max,
pi_upper
()));
167
aTanProject
(
r
,x1,iv_min,iv_max,n_min,n_max);
168
FloatNum
n_iv_min =
r
.add_down(iv_min,
r
.mul_down(n_min,
pi_upper
()));
169
FloatNum
n_iv_max =
r
.add_up (iv_max,
r
.mul_down(n_max,
pi_upper
()));
170
if
(n_iv_min > n_iv_max)
return
ES_FAILED
;
171
GECODE_ME_CHECK
(x0.eq(home,
FloatVal
(n_iv_min,n_iv_max)));
172
GECODE_ME_CHECK
(x1.eq(home,
tan
(x0.val())));
// Redo tan because with x0 reduction, sin may be more accurate
173
}
174
175
return
(x0.assigned()) ? home.
ES_SUBSUMED
(*
this
) :
ES_FIX
;
176
}
177
178
/*
179
* Bounds consistent arc tangent operator
180
*
181
*/
182
183
template
<
class
A,
class
B>
184
forceinline
185
ATan<A,B>::ATan
(
Home
home, A x0, B x1)
186
:
MixBinaryPropagator
<A,
PC_FLOAT_BND
,B,
PC_FLOAT_BND
>(home,x0,x1) {}
187
188
template
<
class
A,
class
B>
189
ExecStatus
190
ATan<A,B>::post
(
Home
home, A x0, B x1) {
191
if
(
same
(x0,x1)) {
192
GECODE_ME_CHECK
(x0.eq(home,0.0));
193
}
else
{
194
(void)
new
(home)
ATan<A,B>
(home,x0,x1);
195
}
196
return
ES_OK
;
197
}
198
199
200
template
<
class
A,
class
B>
201
forceinline
202
ATan<A,B>::ATan
(
Space
& home,
bool
share,
ATan<A,B>
&
p
)
203
:
MixBinaryPropagator
<A,
PC_FLOAT_BND
,B,
PC_FLOAT_BND
>(home,share,
p
) {}
204
205
template
<
class
A,
class
B>
206
Actor
*
207
ATan<A,B>::copy
(
Space
& home,
bool
share) {
208
return
new
(home)
ATan<A,B>
(home,share,*
this
);
209
}
210
211
template
<
class
A,
class
B>
212
ExecStatus
213
ATan<A,B>::propagate
(
Space
& home,
const
ModEventDelta
&) {
214
GECODE_ME_CHECK
(x1.eq(home,
atan
(x0.domain())));
215
GECODE_ME_CHECK
(x0.eq(home,
tan
(x1.domain())));
216
return
(x0.assigned() && x1.assigned()) ? home.
ES_SUBSUMED
(*
this
) :
ES_FIX
;
217
}
218
219
}}}
220
221
// STATISTICS: float-prop
222
Gecode::Float::Trigonometric::ATan::post
static ExecStatus post(Home home, A x0, B x1)
Post propagator for .
Definition:
tanatan.hpp:190
forceinline
#define forceinline
Definition:
config.hpp:173
Gecode::Space::ES_SUBSUMED
ExecStatus ES_SUBSUMED(Propagator &p)
Definition:
core.hpp:3614
ATANINF_DOWN
#define ATANINF_DOWN
Gecode::Float::Trigonometric::ATan::copy
virtual Actor * copy(Space &home, bool share)
Create copy during cloning.
Definition:
tanatan.hpp:207
POS
#define POS(X)
Gecode::Float::PC_FLOAT_BND
const Gecode::PropCond PC_FLOAT_BND
Propagate when minimum or maximum of a view changes.
Definition:
var-type.hpp:292
Gecode::Int::BinPacking::same
bool same(const Item &i, const Item &j)
Whether two items are the same.
Definition:
propagate.hpp:76
t
NodeType t
Type of node.
Definition:
bool-expr.cpp:234
Gecode::Space
Computation spaces.
Definition:
core.hpp:1748
Gecode::Actor
Base-class for both propagators and branchers.
Definition:
core.hpp:696
Gecode::Float::Trigonometric::Tan
Propagator for bounds consistent tangent operator
Definition:
trigonometric.hh:168
Gecode
Gecode toplevel namespace
Gecode::MixBinaryPropagator
Mixed binary propagator.
Definition:
propagator.hpp:213
Gecode::Home
Home class for posting propagators
Definition:
core.hpp:922
Gecode::Float::Trigonometric::Tan::propagate
virtual ExecStatus propagate(Space &home, const ModEventDelta &med)
Perform propagation.
Definition:
tanatan.hpp:127
ATANSUP_UP
#define ATANSUP_UP
Gecode::Float::Trigonometric::ATan
Propagator for bounds consistent arc tangent operator
Definition:
trigonometric.hh:195
Gecode::r
Post propagator for SetVar SetOpType SetVar SetRelType r
Definition:
set.hh:784
Gecode::FloatNum
double FloatNum
Floating point number base type.
Definition:
float.hh:110
Gecode::tan
void tan(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Definition:
trigonometric.cpp:84
Gecode::pi_upper
FloatNum pi_upper(void)
Return upper bound of .
Definition:
num.hpp:53
Gecode::Float::Trigonometric::Tan::post
static ExecStatus post(Home home, A x0, B x1)
Post propagator for .
Definition:
tanatan.hpp:102
Gecode::Float::Trigonometric::aTanProject
void aTanProject(Rounding &r, const V &aTanIv, FloatNum &iv_min, FloatNum &iv_max, int &n_min, int &n_max)
Definition:
tanatan.hpp:45
Gecode::Float::Rounding
Floating point rounding policy.
Definition:
float.hh:158
I0__PI_2I
#define I0__PI_2I
Gecode::Float::Trigonometric::Tan::copy
virtual Actor * copy(Space &home, bool share)
Create copy during cloning.
Definition:
tanatan.hpp:121
GECODE_NEVER
#define GECODE_NEVER
Assert that this command is never executed.
Definition:
macros.hpp:60
Gecode::FloatVal
Float value type.
Definition:
float.hh:338
Gecode::Float::Trigonometric::ATan::ATan
ATan(Space &home, bool share, ATan &p)
Constructor for cloning p.
Definition:
tanatan.hpp:202
Gecode::pi_half_upper
FloatNum pi_half_upper(void)
Return upper bound of .
Definition:
num.hpp:45
Gecode::ES_FIX
@ ES_FIX
Propagation has computed fixpoint.
Definition:
core.hpp:545
Gecode::Float::Trigonometric::Tan::Tan
Tan(Space &home, bool share, Tan &p)
Constructor for cloning p.
Definition:
tanatan.hpp:116
GECODE_ME_CHECK
#define GECODE_ME_CHECK(me)
Check whether modification event me is failed, and forward failure.
Definition:
macros.hpp:56
Gecode::atan
void atan(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Definition:
trigonometric.cpp:77
Gecode::Float::Trigonometric::ATan::propagate
virtual ExecStatus propagate(Space &home, const ModEventDelta &med)
Perform propagation.
Definition:
tanatan.hpp:213
Gecode::ES_FAILED
@ ES_FAILED
Execution has resulted in failure.
Definition:
core.hpp:542
Gecode::ModEventDelta
int ModEventDelta
Modification event deltas.
Definition:
core.hpp:169
Gecode::ES_OK
@ ES_OK
Execution is okay.
Definition:
core.hpp:544
p
int p
Number of positive literals for node type.
Definition:
bool-expr.cpp:236
Gecode::ExecStatus
ExecStatus
Definition:
core.hpp:540