Generated on Tue Jul 18 2017 18:41:42 for Gecode by doxygen 1.8.13
float-arith.cpp
Go to the documentation of this file.
1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 /*
3  * Main authors:
4  * Christian Schulte <schulte@gecode.org>
5  * Vincent Barichard <Vincent.Barichard@univ-angers.fr>
6  *
7  * Copyright:
8  * Christian Schulte, 2006
9  * Vincent Barichard, 2012
10  *
11  * Last modified:
12  * $Date: 2016-04-19 17:19:45 +0200 (Tue, 19 Apr 2016) $ by $Author: schulte $
13  * $Revision: 14967 $
14  *
15  * This file is part of Gecode, the generic constraint
16  * development environment:
17  * http://www.gecode.org
18  *
19  * Permission is hereby granted, free of charge, to any person obtaining
20  * a copy of this software and associated documentation files (the
21  * "Software"), to deal in the Software without restriction, including
22  * without limitation the rights to use, copy, modify, merge, publish,
23  * distribute, sublicense, and/or sell copies of the Software, and to
24  * permit persons to whom the Software is furnished to do so, subject to
25  * the following conditions:
26  *
27  * The above copyright notice and this permission notice shall be
28  * included in all copies or substantial portions of the Software.
29  *
30  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37  *
38  */
39 
40 #include <gecode/minimodel.hh>
41 
42 #ifdef GECODE_HAS_FLOAT_VARS
43 
44 namespace Gecode { namespace MiniModel {
45 
48  public NonLinFloatExpr {
49  public:
59 #ifdef GECODE_HAS_MPFR
68 #endif
70  ANLFE_NROOT
71  } t;
75  int n;
77  int aInt;
80  : t(t0), a(heap.alloc<LinFloatExpr>(n0)), n(n0), aInt(-1) {}
82  : t(t0), a(heap.alloc<LinFloatExpr>(n0)), n(n0), aInt(a0) {}
86  virtual FloatVar post(Home home, FloatVar* ret) const {
87  FloatVar y;
88  switch (t) {
89  case ANLFE_ABS:
90  {
91  FloatVar x = a[0].post(home);
92  if (x.min() >= 0)
93  y = result(home,ret,x);
94  else {
95  y = result(home,ret);
96  abs(home, x, y);
97  }
98  }
99  break;
100  case ANLFE_MIN:
101  if (n==1) {
102  y = result(home,ret, a[0].post(home));
103  } else if (n==2) {
104  FloatVar x0 = a[0].post(home);
105  FloatVar x1 = a[1].post(home);
106  if (x0.max() <= x1.min())
107  y = result(home,ret,x0);
108  else if (x1.max() <= x0.min())
109  y = result(home,ret,x1);
110  else {
111  y = result(home,ret);
112  min(home, x0, x1, y);
113  }
114  } else {
115  FloatVarArgs x(n);
116  for (int i=n; i--;)
117  x[i] = a[i].post(home);
118  y = result(home,ret);
119  min(home, x, y);
120  }
121  break;
122  case ANLFE_MAX:
123  if (n==1) {
124  y = result(home,ret,a[0].post(home));
125  } else if (n==2) {
126  FloatVar x0 = a[0].post(home);
127  FloatVar x1 = a[1].post(home);
128  if (x0.max() <= x1.min())
129  y = result(home,ret,x1);
130  else if (x1.max() <= x0.min())
131  y = result(home,ret,x0);
132  else {
133  y = result(home,ret);
134  max(home, x0, x1, y);
135  }
136  } else {
137  FloatVarArgs x(n);
138  for (int i=n; i--;)
139  x[i] = a[i].post(home);
140  y = result(home,ret);
141  max(home, x, y);
142  }
143  break;
144  case ANLFE_MULT:
145  {
146  assert(n == 2);
147  FloatVar x0 = a[0].post(home);
148  FloatVar x1 = a[1].post(home);
149  if (x0.assigned() && (x0.val() == 0.0))
150  y = result(home,ret,x0);
151  else if (x0.assigned() && (x0.val() == 1.0))
152  y = result(home,ret,x1);
153  else if (x1.assigned() && (x1.val() == 0.0))
154  y = result(home,ret,x1);
155  else if (x1.assigned() && (x1.val() == 1.0))
156  y = result(home,ret,x0);
157  else {
158  y = result(home,ret);
159  mult(home, x0, x1, y);
160  }
161  }
162  break;
163  case ANLFE_DIV:
164  {
165  assert(n == 2);
166  FloatVar x0 = a[0].post(home);
167  FloatVar x1 = a[1].post(home);
168  if (x1.assigned() && (x1.val() == 1.0))
169  y = result(home,ret,x0);
170  else if (x0.assigned() && (x0.val() == 0.0))
171  y = result(home,ret,x0);
172  else {
173  y = result(home,ret);
174  div(home, x0, x1, y);
175  }
176  }
177  break;
178  case ANLFE_SQR:
179  {
180  assert(n == 1);
181  FloatVar x = a[0].post(home);
182  if (x.assigned() && ((x.val() == 0.0) || (x.val() == 1.0)))
183  y = x;
184  else {
185  y = result(home,ret);
186  sqr(home, x, y);
187  }
188  }
189  break;
190  case ANLFE_SQRT:
191  {
192  assert(n == 1);
193  FloatVar x = a[0].post(home);
194  if (x.assigned() && ((x.val() == 0.0) || (x.val() == 1.0)))
195  y = result(home,ret,x);
196  else {
197  y = result(home,ret);
198  sqrt(home, x, y);
199  }
200  }
201  break;
202  case ANLFE_POW:
203  {
204  assert(n == 1);
205  FloatVar x = a[0].post(home);
206  if (x.assigned() && ((x.val() == 0.0) || (x.val() == 1.0)))
207  y = result(home,ret,x);
208  else {
209  y = result(home,ret);
210  pow(home, x, aInt, y);
211  }
212  }
213  break;
214  case ANLFE_NROOT:
215  {
216  assert(n == 1);
217  FloatVar x = a[0].post(home);
218  if (x.assigned() && ((x.val() == 0.0) || (x.val() == 1.0)))
219  y = result(home,ret,x);
220  else {
221  y = result(home,ret);
222  nroot(home, x, aInt, y);
223  }
224  }
225  break;
226 #ifdef GECODE_HAS_MPFR
227  case ANLFE_EXP:
228  {
229  assert(n == 1);
230  FloatVar x = a[0].post(home);
231  if (x.assigned() && (x.val() == 0.0))
232  y = result(home,ret,x);
233  else {
234  y = result(home,ret);
235  exp(home, x, y);
236  }
237  }
238  break;
239  case ANLFE_LOG:
240  {
241  assert(n == 1);
242  FloatVar x = a[0].post(home);
243  y = result(home,ret);
244  log(home, x, y);
245  }
246  break;
247  case ANLFE_ASIN:
248  {
249  assert(n == 1);
250  FloatVar x = a[0].post(home);
251  y = result(home,ret);
252  asin(home, x, y);
253  }
254  break;
255  case ANLFE_SIN:
256  {
257  assert(n == 1);
258  FloatVar x = a[0].post(home);
259  y = result(home,ret);
260  sin(home, x, y);
261  }
262  break;
263  case ANLFE_ACOS:
264  {
265  assert(n == 1);
266  FloatVar x = a[0].post(home);
267  y = result(home,ret);
268  acos(home, x, y);
269  }
270  break;
271  case ANLFE_COS:
272  {
273  assert(n == 1);
274  FloatVar x = a[0].post(home);
275  y = result(home,ret);
276  cos(home, x, y);
277  }
278  break;
279  case ANLFE_ATAN:
280  {
281  assert(n == 1);
282  FloatVar x = a[0].post(home);
283  y = result(home,ret);
284  atan(home, x, y);
285  }
286  break;
287  case ANLFE_TAN:
288  {
289  assert(n == 1);
290  FloatVar x = a[0].post(home);
291  y = result(home,ret);
292  tan(home, x, y);
293  }
294  break;
295 #endif
296  default:
297  GECODE_NEVER;
298  }
299  return y;
300  }
301  virtual void post(Home home, FloatRelType frt, FloatVal c) const {
302  if ((t == ANLFE_MIN && frt == FRT_GQ) ||
303  (t == ANLFE_MAX && frt == FRT_LQ)) {
304  FloatVarArgs x(n);
305  for (int i=n; i--;)
306  x[i] = a[i].post(home);
307  rel(home, x, frt, c);
308  } else {
309  rel(home, post(home,NULL), frt, c);
310  }
311  }
312  virtual void post(Home home, FloatRelType frt, FloatVal c,
313  BoolVar b) const {
314  rel(home, post(home,NULL), frt, c, b);
315  }
316  };
319  return e.nlfe() &&
320  dynamic_cast<ArithNonLinFloatExpr*>(e.nlfe()) != NULL &&
321  dynamic_cast<ArithNonLinFloatExpr*>(e.nlfe())->t == t;
322  }
323 
324 }}
325 
326 namespace Gecode {
327 
329  abs(const LinFloatExpr& e) {
330  using namespace MiniModel;
332  return e;
333  ArithNonLinFloatExpr* ae =
334  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_ABS,1);
335  ae->a[0] = e;
336  return LinFloatExpr(ae);
337  }
338 
340  min(const LinFloatExpr& e0, const LinFloatExpr& e1) {
341  using namespace MiniModel;
342  int n = 0;
344  n += static_cast<ArithNonLinFloatExpr*>(e0.nlfe())->n;
345  else
346  n += 1;
348  n += static_cast<ArithNonLinFloatExpr*>(e1.nlfe())->n;
349  else
350  n += 1;
351  ArithNonLinFloatExpr* ae =
352  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MIN,n);
353  int i=0;
355  ArithNonLinFloatExpr* e0e = static_cast<ArithNonLinFloatExpr*>(e0.nlfe());
356  for (; i<e0e->n; i++)
357  ae->a[i] = e0e->a[i];
358  } else {
359  ae->a[i++] = e0;
360  }
362  ArithNonLinFloatExpr* e1e = static_cast<ArithNonLinFloatExpr*>(e1.nlfe());
363  int curN = i;
364  for (; i<curN+e1e->n; i++)
365  ae->a[i] = e1e->a[i-curN];
366  } else {
367  ae->a[i++] = e1;
368  }
369  return LinFloatExpr(ae);
370  }
371 
373  min(const FloatVarArgs& x) {
374  using namespace MiniModel;
375  ArithNonLinFloatExpr* ae =
376  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MIN,x.size());
377  for (int i=x.size(); i--;)
378  ae->a[i] = x[i];
379  return LinFloatExpr(ae);
380  }
381 
383  max(const LinFloatExpr& e0, const LinFloatExpr& e1) {
384  using namespace MiniModel;
385  int n = 0;
387  n += static_cast<ArithNonLinFloatExpr*>(e0.nlfe())->n;
388  else
389  n += 1;
391  n += static_cast<ArithNonLinFloatExpr*>(e1.nlfe())->n;
392  else
393  n += 1;
394  ArithNonLinFloatExpr* ae =
395  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MAX,n);
396  int i=0;
398  ArithNonLinFloatExpr* e0e = static_cast<ArithNonLinFloatExpr*>(e0.nlfe());
399  for (; i<e0e->n; i++)
400  ae->a[i] = e0e->a[i];
401  } else {
402  ae->a[i++] = e0;
403  }
405  ArithNonLinFloatExpr* e1e = static_cast<ArithNonLinFloatExpr*>(e1.nlfe());
406  int curN = i;
407  for (; i<curN+e1e->n; i++)
408  ae->a[i] = e1e->a[i-curN];
409  } else {
410  ae->a[i++] = e1;
411  }
412  return LinFloatExpr(ae);
413  }
414 
416  max(const FloatVarArgs& x) {
417  using namespace MiniModel;
418  ArithNonLinFloatExpr* ae =
419  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MAX,x.size());
420  for (int i=x.size(); i--;)
421  ae->a[i] = x[i];
422  return LinFloatExpr(ae);
423  }
424 
426  operator *(const FloatVar& e0, const FloatVar& e1) {
427  using namespace MiniModel;
428  ArithNonLinFloatExpr* ae =
429  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MULT,2);
430  ae->a[0] = e0;
431  ae->a[1] = e1;
432  return LinFloatExpr(ae);
433  }
434 
436  operator *(const LinFloatExpr& e0, const FloatVar& e1) {
437  using namespace MiniModel;
438  ArithNonLinFloatExpr* ae =
439  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MULT,2);
440  ae->a[0] = e0;
441  ae->a[1] = e1;
442  return LinFloatExpr(ae);
443  }
444 
446  operator *(const FloatVar& e0, const LinFloatExpr& e1) {
447  using namespace MiniModel;
448  ArithNonLinFloatExpr* ae =
449  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MULT,2);
450  ae->a[0] = e0;
451  ae->a[1] = e1;
452  return LinFloatExpr(ae);
453  }
454 
456  operator *(const LinFloatExpr& e0, const LinFloatExpr& e1) {
457  using namespace MiniModel;
458  ArithNonLinFloatExpr* ae =
459  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MULT,2);
460  ae->a[0] = e0;
461  ae->a[1] = e1;
462  return LinFloatExpr(ae);
463  }
464 
466  operator /(const LinFloatExpr& e0, const LinFloatExpr& e1) {
467  using namespace MiniModel;
468  ArithNonLinFloatExpr* ae =
469  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_DIV,2);
470  ae->a[0] = e0;
471  ae->a[1] = e1;
472  return LinFloatExpr(ae);
473  }
474 
476  sqr(const LinFloatExpr& e) {
477  using namespace MiniModel;
478  ArithNonLinFloatExpr* ae =
479  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_SQR,1);
480  ae->a[0] = e;
481  return LinFloatExpr(ae);
482  }
483 
485  sqrt(const LinFloatExpr& e) {
486  using namespace MiniModel;
487  ArithNonLinFloatExpr* ae =
488  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_SQRT,1);
489  ae->a[0] = e;
490  return LinFloatExpr(ae);
491  }
492 
494  pow(const LinFloatExpr& e, int exp) {
495  using namespace MiniModel;
496  ArithNonLinFloatExpr* ae =
497  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_POW,1,exp);
498  ae->a[0] = e;
499  return LinFloatExpr(ae);
500  }
501 
503  nroot(const LinFloatExpr& e, int exp) {
504  using namespace MiniModel;
505  ArithNonLinFloatExpr* ae =
506  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_NROOT,1,exp);
507  ae->a[0] = e;
508  return LinFloatExpr(ae);
509  }
510 
511 #ifdef GECODE_HAS_MPFR
512 
514  exp(const LinFloatExpr& e) {
515  using namespace MiniModel;
516  ArithNonLinFloatExpr* ae =
517  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_EXP,1);
518  ae->a[0] = e;
519  return LinFloatExpr(ae);
520  }
521 
523  log(const LinFloatExpr& e) {
524  using namespace MiniModel;
525  ArithNonLinFloatExpr* ae =
526  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_LOG,1);
527  ae->a[0] = e;
528  return LinFloatExpr(ae);
529  }
530 
532  asin(const LinFloatExpr& e) {
533  using namespace MiniModel;
534  ArithNonLinFloatExpr* ae =
535  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_ASIN,1);
536  ae->a[0] = e;
537  return LinFloatExpr(ae);
538  }
539 
541  sin(const LinFloatExpr& e) {
542  using namespace MiniModel;
543  ArithNonLinFloatExpr* ae =
544  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_SIN,1);
545  ae->a[0] = e;
546  return LinFloatExpr(ae);
547  }
548 
550  acos(const LinFloatExpr& e) {
551  using namespace MiniModel;
552  ArithNonLinFloatExpr* ae =
553  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_ACOS,1);
554  ae->a[0] = e;
555  return LinFloatExpr(ae);
556  }
557 
559  cos(const LinFloatExpr& e) {
560  using namespace MiniModel;
561  ArithNonLinFloatExpr* ae =
562  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_COS,1);
563  ae->a[0] = e;
564  return LinFloatExpr(ae);
565  }
566 
568  atan(const LinFloatExpr& e) {
569  using namespace MiniModel;
570  ArithNonLinFloatExpr* ae =
571  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_ATAN,1);
572  ae->a[0] = e;
573  return LinFloatExpr(ae);
574  }
575 
577  tan(const LinFloatExpr& e) {
578  using namespace MiniModel;
579  ArithNonLinFloatExpr* ae =
580  new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_TAN,1);
581  ae->a[0] = e;
582  return LinFloatExpr(ae);
583  }
584 
585 #endif
586 
587 }
588 
589 #endif
590 
591 // STATISTICS: minimodel-any
NodeType t
Type of node.
Definition: bool-expr.cpp:234
void mult(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition: arithmetic.cpp:92
int size(void) const
Return size of array (number of elements)
Definition: array.hpp:1669
ArithNonLinFloatExprType
The expression type.
Definition: float-arith.cpp:51
ArithNonLinFloatExpr(ArithNonLinFloatExprType t0, int n0, int a0)
Definition: float-arith.cpp:81
void log(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
FloatVal operator/(const FloatVal &x, const FloatVal &y)
Definition: val.hpp:217
FloatNum max(void) const
Return maximum of domain.
Definition: float.hpp:71
Less or equal ( )
Definition: float.hh:1072
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition: arithmetic.cpp:53
void abs(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Definition: arithmetic.cpp:45
ArithNonLinFloatExpr(ArithNonLinFloatExprType t0, int n0)
Constructors.
Definition: float-arith.cpp:79
bool assigned(void) const
Test whether view is assigned.
Definition: var.hpp:123
Passing float variables.
Definition: float.hh:981
void nroot(Home home, FloatVar x0, int n, FloatVar x1)
Post propagator for for $n 0$.
Definition: arithmetic.cpp:122
int aInt
Integer argument (used in nroot for example)
Definition: float-arith.cpp:77
void pow(Home home, FloatVar x0, int n, FloatVar x1)
Post propagator for for $n 0$.
Definition: arithmetic.cpp:113
Non-linear float arithmetic expressions.
Definition: float-arith.cpp:47
FloatVal val(void) const
Return assigned value.
Definition: float.hpp:57
bool hasType(const LinFloatExpr &e, ArithNonLinFloatExpr::ArithNonLinFloatExprType t)
Check if e is of type t.
FloatNum min(void) const
Return minimum of domain.
Definition: float.hpp:63
struct Gecode::@579::NNF::@61::@63 a
For atomic nodes.
Gecode::FloatVal c(-8, 8)
Greater or equal ( )
Definition: float.hh:1074
Gecode::IntArgs i(4, 1, 2, 3, 4)
int n
Number of negative literals for node type.
Definition: bool-expr.cpp:238
Base class for non-linear float expressions.
Definition: minimodel.hh:690
void sqr(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Definition: arithmetic.cpp:99
FloatRelType
Relation types for floats.
Definition: float.hh:1069
virtual void post(Home home, FloatRelType frt, FloatVal c) const
Post expression to be in relation frt with c.
void sqrt(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Definition: arithmetic.cpp:106
struct Gecode::@579::NNF::@61::@62 b
For binary nodes (and, or, eqv)
Float expressions
Definition: minimodel.hh:720
void asin(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Boolean integer variables.
Definition: int.hh:494
LinFloatExpr * a
Expressions.
Definition: float-arith.cpp:73
void min(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition: arithmetic.cpp:71
void cos(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
virtual FloatVar post(Home home, FloatVar *ret) const
Post expression.
Definition: float-arith.cpp:86
Post propagator for SetVar SetOpType SetVar y
Definition: set.hh:784
void div(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition: arithmetic.cpp:131
Float value type.
Definition: float.hh:338
FloatVal operator*(const FloatVal &x, const FloatVal &y)
Definition: val.hpp:204
void free(T *b, long unsigned int n)
Delete n objects starting at b.
Definition: heap.hpp:461
void tan(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Heap heap
The single global heap.
Definition: heap.cpp:48
void rel(Home home, FloatVar x0, FloatRelType frt, FloatVal n)
Propagates .
Definition: rel.cpp:47
Post propagator for SetVar x
Definition: set.hh:784
#define GECODE_MINIMODEL_EXPORT
Definition: minimodel.hh:80
Float variables.
Definition: float.hh:874
Gecode toplevel namespace
void sin(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
NonLinFloatExpr * nlfe(void) const
Return non-linear expression inside, or NULL if not non-linear.
Definition: float-expr.cpp:142
void acos(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void exp(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Home class for posting propagators
Definition: core.hpp:922
#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 .
int n
Size of variable array.
Definition: float-arith.cpp:75
TFE post(PropagatorGroup g)
Only post functions (but not propagators) from g are considered.
T * a
Element array.
Definition: array.hpp:531
void post(Home home, FloatRelType frt) const
Post propagator.
Definition: float-expr.cpp:156
virtual void post(Home home, FloatRelType frt, FloatVal c, BoolVar b) const
Post reified expression to be in relation frt with c.