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