Generated on Sat Feb 7 2015 02:01:17 for Gecode by doxygen 1.8.9.1
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: 2013-02-04 21:28:39 +0100 (Mon, 04 Feb 2013) $ by $Author: schulte $
11  * $Revision: 13262 $
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:
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:
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>
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>
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
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>
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>
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
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 
FloatNum pi_half_upper(void)
Return upper bound of .
Definition: num.hpp:45
void aTanProject(Rounding &r, const V &aTanIv, FloatNum &iv_min, FloatNum &iv_max, int &n_min, int &n_max)
Definition: tanatan.hpp:45
#define ATANINF_DOWN
NodeType t
Type of node.
Definition: bool-expr.cpp:234
FloatNum add_down(FloatNum x, FloatNum y)
Return lower bound of x plus y (domain: )
FloatNum div_up(FloatNum x, FloatNum y)
Return upper bound of x divided y (domain: )
FloatNum mul_down(FloatNum x, FloatNum y)
Return lower bound of x times y (domain: )
Tan(Space &home, bool share, Tan &p)
Constructor for cloning p.
Definition: tanatan.hpp:116
static ExecStatus post(Home home, A x0, B x1)
Post propagator for .
Definition: tanatan.hpp:190
ExecStatus ES_SUBSUMED(Propagator &p)
Definition: core.hpp:2973
virtual Actor * copy(Space &home, bool share)
Create copy during cloning.
Definition: tanatan.hpp:121
Propagator for bounds consistent arc tangent operator
virtual Actor * copy(Space &home, bool share)
Create copy during cloning.
Definition: tanatan.hpp:207
#define ATANSUP_UP
Propagation has computed fixpoint.
Definition: core.hpp:528
Computation spaces.
Definition: core.hpp:1362
Base-class for both propagators and branchers.
Definition: core.hpp:666
Propagator for bounds consistent tangent operator
int p
Number of positive literals for node type.
Definition: bool-expr.cpp:236
bool same(const ConstView< ViewA > &, const ConstView< ViewB > &)
Test whether two views are the same.
Definition: view.hpp:603
Execution has resulted in failure.
Definition: core.hpp:525
NNF * r
Right subtree.
Definition: bool-expr.cpp:246
#define POS(X)
static ExecStatus post(Home home, A x0, B x1)
Post propagator for .
Definition: tanatan.hpp:102
#define GECODE_ME_CHECK(me)
Check whether modification event me is failed, and forward failure.
Definition: macros.hpp:45
Floating point rounding policy.
Definition: float.hh:137
FloatNum tan_up(FloatNum x)
Return upper bound of tangent of x (domain: )
ATan(Space &home, bool share, ATan &p)
Constructor for cloning p.
Definition: tanatan.hpp:202
Float value type.
Definition: float.hh:321
virtual ExecStatus propagate(Space &home, const ModEventDelta &med)
Perform propagation.
Definition: tanatan.hpp:127
FloatNum sub_down(FloatNum x, FloatNum y)
Return lower bound of x minus y (domain: )
Mixed binary propagator.
Definition: propagator.hpp:203
void tan(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Definition: arithmetic.cpp:210
ExecStatus
Definition: core.hpp:523
#define forceinline
Definition: config.hpp:132
Execution is okay.
Definition: core.hpp:527
const Gecode::PropCond PC_FLOAT_BND
Propagate when minimum or maximum of a view changes.
Definition: var-type.hpp:292
virtual ExecStatus propagate(Space &home, const ModEventDelta &med)
Perform propagation.
Definition: tanatan.hpp:213
FloatNum sub_up(FloatNum x, FloatNum y)
Return upper bound of x minus y (domain: )
FloatNum add_up(FloatNum x, FloatNum y)
Return upper bound of x plus y (domain: )
Gecode toplevel namespace
#define I0__PI_2I
FloatNum mul_up(FloatNum x, FloatNum y)
Return upper bound of x times y (domain: )
int ModEventDelta
Modification event deltas.
Definition: core.hpp:173
Home class for posting propagators
Definition: core.hpp:717
double FloatNum
Floating point number base type.
Definition: float.hh:108
#define GECODE_NEVER
Assert that this command is never executed.
Definition: macros.hpp:60
void atan(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Definition: arithmetic.cpp:203
FloatNum tan_down(FloatNum x)
Return lower bound of tangent of x (domain: )
FloatNum pi_upper(void)
Return upper bound of .
Definition: num.hpp:53