Generated on Tue Feb 11 2025 17:33:26 for Gecode by doxygen 1.12.0
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
40namespace Gecode { namespace MiniModel {
41
44 public NonLinFloatExpr {
45 public:
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 {
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 {
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 (aInt >= 0))
204 y = result(home,ret,x);
205 else {
206 y = result(home,ret);
207 pow(home, x, aInt, y);
208 }
209 }
210 break;
211 case ANLFE_NROOT:
212 {
213 assert(n == 1);
214 FloatVar x = a[0].post(home);
215 if (x.assigned() && ((x.val() == 0.0) || (x.val() == 1.0)) &&
216 (aInt >= 0))
217 y = result(home,ret,x);
218 else {
219 y = result(home,ret);
220 nroot(home, x, aInt, y);
221 }
222 }
223 break;
224#ifdef GECODE_HAS_MPFR
225 case ANLFE_EXP:
226 {
227 assert(n == 1);
228 FloatVar x = a[0].post(home);
229 if (x.assigned() && (x.val() == 0.0)) {
230 FloatVar one(home,1.0,1.0);
231 y = result(home,ret,one);
232 } else {
233 y = result(home,ret);
234 exp(home, x, y);
235 }
236 }
237 break;
238 case ANLFE_LOG:
239 {
240 assert(n == 1);
241 FloatVar x = a[0].post(home);
242 y = result(home,ret);
243 log(home, x, y);
244 }
245 break;
246 case ANLFE_ASIN:
247 {
248 assert(n == 1);
249 FloatVar x = a[0].post(home);
250 y = result(home,ret);
251 asin(home, x, y);
252 }
253 break;
254 case ANLFE_SIN:
255 {
256 assert(n == 1);
257 FloatVar x = a[0].post(home);
258 y = result(home,ret);
259 sin(home, x, y);
260 }
261 break;
262 case ANLFE_ACOS:
263 {
264 assert(n == 1);
265 FloatVar x = a[0].post(home);
266 y = result(home,ret);
267 acos(home, x, y);
268 }
269 break;
270 case ANLFE_COS:
271 {
272 assert(n == 1);
273 FloatVar x = a[0].post(home);
274 y = result(home,ret);
275 cos(home, x, y);
276 }
277 break;
278 case ANLFE_ATAN:
279 {
280 assert(n == 1);
281 FloatVar x = a[0].post(home);
282 y = result(home,ret);
283 atan(home, x, y);
284 }
285 break;
286 case ANLFE_TAN:
287 {
288 assert(n == 1);
289 FloatVar x = a[0].post(home);
290 y = result(home,ret);
291 tan(home, x, y);
292 }
293 break;
294#endif
295 default:
297 }
298 return y;
299 }
300 virtual void post(Home home, FloatRelType frt, FloatVal c) const {
301 if ((t == ANLFE_MIN && frt == FRT_GQ) ||
302 (t == ANLFE_MAX && frt == FRT_LQ)) {
304 for (int i=n; i--;)
305 x[i] = a[i].post(home);
306 rel(home, x, frt, c);
307 } else {
308 rel(home, post(home,nullptr), frt, c);
309 }
310 }
311 virtual void post(Home home, FloatRelType frt, FloatVal c,
312 BoolVar b) const {
313 rel(home, post(home,nullptr), frt, c, b);
314 }
315 };
318 return e.nlfe() &&
319 dynamic_cast<ArithNonLinFloatExpr*>(e.nlfe()) != nullptr &&
320 dynamic_cast<ArithNonLinFloatExpr*>(e.nlfe())->t == t;
321 }
322
323}}
324
325namespace Gecode {
326
327 LinFloatExpr
328 abs(const LinFloatExpr& e) {
329 using namespace MiniModel;
330 if (hasType(e, ArithNonLinFloatExpr::ANLFE_ABS))
331 return e;
332 ArithNonLinFloatExpr* ae =
333 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_ABS,1);
334 ae->a[0] = e;
335 return LinFloatExpr(ae);
336 }
337
338 LinFloatExpr
339 min(const LinFloatExpr& e0, const LinFloatExpr& e1) {
340 using namespace MiniModel;
341 int n = 0;
342 if (hasType(e0, ArithNonLinFloatExpr::ANLFE_MIN))
343 n += static_cast<ArithNonLinFloatExpr*>(e0.nlfe())->n;
344 else
345 n += 1;
346 if (hasType(e1, ArithNonLinFloatExpr::ANLFE_MIN))
347 n += static_cast<ArithNonLinFloatExpr*>(e1.nlfe())->n;
348 else
349 n += 1;
350 ArithNonLinFloatExpr* ae =
351 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MIN,n);
352 int i=0;
353 if (hasType(e0, ArithNonLinFloatExpr::ANLFE_MIN)) {
354 ArithNonLinFloatExpr* e0e = static_cast<ArithNonLinFloatExpr*>(e0.nlfe());
355 for (; i<e0e->n; i++)
356 ae->a[i] = e0e->a[i];
357 } else {
358 ae->a[i++] = e0;
359 }
360 if (hasType(e1, ArithNonLinFloatExpr::ANLFE_MIN)) {
361 ArithNonLinFloatExpr* e1e = static_cast<ArithNonLinFloatExpr*>(e1.nlfe());
362 int curN = i;
363 for (; i<curN+e1e->n; i++)
364 ae->a[i] = e1e->a[i-curN];
365 } else {
366 ae->a[i++] = e1;
367 }
368 return LinFloatExpr(ae);
369 }
370
371 LinFloatExpr
373 using namespace MiniModel;
374 ArithNonLinFloatExpr* ae =
375 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MIN,x.size());
376 for (int i=x.size(); i--;)
377 ae->a[i] = x[i];
378 return LinFloatExpr(ae);
379 }
380
381 LinFloatExpr
382 max(const LinFloatExpr& e0, const LinFloatExpr& e1) {
383 using namespace MiniModel;
384 int n = 0;
385 if (hasType(e0, ArithNonLinFloatExpr::ANLFE_MAX))
386 n += static_cast<ArithNonLinFloatExpr*>(e0.nlfe())->n;
387 else
388 n += 1;
389 if (hasType(e1, ArithNonLinFloatExpr::ANLFE_MAX))
390 n += static_cast<ArithNonLinFloatExpr*>(e1.nlfe())->n;
391 else
392 n += 1;
393 ArithNonLinFloatExpr* ae =
394 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MAX,n);
395 int i=0;
396 if (hasType(e0, ArithNonLinFloatExpr::ANLFE_MAX)) {
397 ArithNonLinFloatExpr* e0e = static_cast<ArithNonLinFloatExpr*>(e0.nlfe());
398 for (; i<e0e->n; i++)
399 ae->a[i] = e0e->a[i];
400 } else {
401 ae->a[i++] = e0;
402 }
403 if (hasType(e1, ArithNonLinFloatExpr::ANLFE_MAX)) {
404 ArithNonLinFloatExpr* e1e = static_cast<ArithNonLinFloatExpr*>(e1.nlfe());
405 int curN = i;
406 for (; i<curN+e1e->n; i++)
407 ae->a[i] = e1e->a[i-curN];
408 } else {
409 ae->a[i++] = e1;
410 }
411 return LinFloatExpr(ae);
412 }
413
414 LinFloatExpr
416 using namespace MiniModel;
417 ArithNonLinFloatExpr* ae =
418 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MAX,x.size());
419 for (int i=x.size(); i--;)
420 ae->a[i] = x[i];
421 return LinFloatExpr(ae);
422 }
423
424 LinFloatExpr
425 operator *(const FloatVar& e0, const FloatVar& e1) {
426 using namespace MiniModel;
427 ArithNonLinFloatExpr* ae =
428 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MULT,2);
429 ae->a[0] = e0;
430 ae->a[1] = e1;
431 return LinFloatExpr(ae);
432 }
433
434 LinFloatExpr
435 operator *(const LinFloatExpr& e0, const FloatVar& e1) {
436 using namespace MiniModel;
437 ArithNonLinFloatExpr* ae =
438 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MULT,2);
439 ae->a[0] = e0;
440 ae->a[1] = e1;
441 return LinFloatExpr(ae);
442 }
443
444 LinFloatExpr
445 operator *(const FloatVar& e0, const LinFloatExpr& e1) {
446 using namespace MiniModel;
447 ArithNonLinFloatExpr* ae =
448 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MULT,2);
449 ae->a[0] = e0;
450 ae->a[1] = e1;
451 return LinFloatExpr(ae);
452 }
453
454 LinFloatExpr
455 operator *(const LinFloatExpr& e0, const LinFloatExpr& e1) {
456 using namespace MiniModel;
457 ArithNonLinFloatExpr* ae =
458 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_MULT,2);
459 ae->a[0] = e0;
460 ae->a[1] = e1;
461 return LinFloatExpr(ae);
462 }
463
464 LinFloatExpr
465 operator /(const LinFloatExpr& e0, const LinFloatExpr& e1) {
466 using namespace MiniModel;
467 ArithNonLinFloatExpr* ae =
468 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_DIV,2);
469 ae->a[0] = e0;
470 ae->a[1] = e1;
471 return LinFloatExpr(ae);
472 }
473
474 LinFloatExpr
475 sqr(const LinFloatExpr& e) {
476 using namespace MiniModel;
477 ArithNonLinFloatExpr* ae =
478 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_SQR,1);
479 ae->a[0] = e;
480 return LinFloatExpr(ae);
481 }
482
483 LinFloatExpr
484 sqrt(const LinFloatExpr& e) {
485 using namespace MiniModel;
486 ArithNonLinFloatExpr* ae =
487 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_SQRT,1);
488 ae->a[0] = e;
489 return LinFloatExpr(ae);
490 }
491
492 LinFloatExpr
493 pow(const LinFloatExpr& e, int exp) {
494 using namespace MiniModel;
495 ArithNonLinFloatExpr* ae =
496 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_POW,1,exp);
497 ae->a[0] = e;
498 return LinFloatExpr(ae);
499 }
500
501 LinFloatExpr
502 nroot(const LinFloatExpr& e, int exp) {
503 using namespace MiniModel;
504 ArithNonLinFloatExpr* ae =
505 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_NROOT,1,exp);
506 ae->a[0] = e;
507 return LinFloatExpr(ae);
508 }
509
510#ifdef GECODE_HAS_MPFR
511
512 LinFloatExpr
513 exp(const LinFloatExpr& e) {
514 using namespace MiniModel;
515 ArithNonLinFloatExpr* ae =
516 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_EXP,1);
517 ae->a[0] = e;
518 return LinFloatExpr(ae);
519 }
520
521 LinFloatExpr
522 log(const LinFloatExpr& e) {
523 using namespace MiniModel;
524 ArithNonLinFloatExpr* ae =
525 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_LOG,1);
526 ae->a[0] = e;
527 return LinFloatExpr(ae);
528 }
529
530 LinFloatExpr
531 asin(const LinFloatExpr& e) {
532 using namespace MiniModel;
533 ArithNonLinFloatExpr* ae =
534 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_ASIN,1);
535 ae->a[0] = e;
536 return LinFloatExpr(ae);
537 }
538
539 LinFloatExpr
540 sin(const LinFloatExpr& e) {
541 using namespace MiniModel;
542 ArithNonLinFloatExpr* ae =
543 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_SIN,1);
544 ae->a[0] = e;
545 return LinFloatExpr(ae);
546 }
547
548 LinFloatExpr
549 acos(const LinFloatExpr& e) {
550 using namespace MiniModel;
551 ArithNonLinFloatExpr* ae =
552 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_ACOS,1);
553 ae->a[0] = e;
554 return LinFloatExpr(ae);
555 }
556
557 LinFloatExpr
558 cos(const LinFloatExpr& e) {
559 using namespace MiniModel;
560 ArithNonLinFloatExpr* ae =
561 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_COS,1);
562 ae->a[0] = e;
563 return LinFloatExpr(ae);
564 }
565
566 LinFloatExpr
567 atan(const LinFloatExpr& e) {
568 using namespace MiniModel;
569 ArithNonLinFloatExpr* ae =
570 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_ATAN,1);
571 ae->a[0] = e;
572 return LinFloatExpr(ae);
573 }
574
575 LinFloatExpr
576 tan(const LinFloatExpr& e) {
577 using namespace MiniModel;
578 ArithNonLinFloatExpr* ae =
579 new ArithNonLinFloatExpr(ArithNonLinFloatExpr::ANLFE_TAN,1);
580 ae->a[0] = e;
581 return LinFloatExpr(ae);
582 }
583
584#endif
585
586}
587
588#endif
589
590// STATISTICS: minimodel-any
struct Gecode::@603::NNF::@65::@66 b
For binary nodes (and, or, eqv)
NodeType t
Type of node.
int n
Number of negative literals for node type.
struct Gecode::@603::NNF::@65::@67 a
For atomic nodes.
Node * x
Pointer to corresponding Boolean expression node.
T * a
Element array.
Definition array.hpp:544
int n
Number of elements.
Definition array.hpp:540
Boolean integer variables.
Definition int.hh:512
Float value type.
Definition float.hh:334
Passing float variables.
Definition float.hh:979
Float variables.
Definition float.hh:870
FloatNum min(void) const
Return minimum of domain.
Definition float.hpp:59
FloatVal val(void) const
Return assigned value.
Definition float.hpp:53
FloatNum max(void) const
Return maximum of domain.
Definition float.hpp:67
void free(T *b, long unsigned int n)
Delete n objects starting at b.
Definition heap.hpp:457
Home class for posting propagators
Definition core.hpp:856
Float expressions
Definition minimodel.hh:822
NonLinFloatExpr * nlfe(void) const
Return non-linear expression inside, or null if not non-linear.
Non-linear float arithmetic expressions.
virtual void post(Home home, FloatRelType frt, FloatVal c, BoolVar b) const
Post reified expression to be in relation frt with c.
virtual void post(Home home, FloatRelType frt, FloatVal c) const
Post expression to be in relation frt with c.
virtual FloatVar post(Home home, FloatVar *ret) const
Post expression.
ArithNonLinFloatExpr(ArithNonLinFloatExprType t0, int n0)
Constructors.
int aInt
Integer argument (used in nroot for example)
ArithNonLinFloatExpr(ArithNonLinFloatExprType t0, int n0, int a0)
@ ANLFE_MULT
Multiplication expression.
@ ANLFE_ABS
Absolute value expression.
@ ANLFE_LOG
Logarithm root expression.
@ ANLFE_SQRT
Square root expression.
enum Gecode::MiniModel::ArithNonLinFloatExpr::ArithNonLinFloatExprType t
Base class for non-linear float expressions.
Definition minimodel.hh:794
bool assigned(void) const
Test whether view is assigned.
Definition var.hpp:111
Heap heap
The single global heap.
Definition heap.cpp:44
void rel(Home home, FloatVar x0, FloatRelType frt, FloatVar x1)
Post propagator for .
Definition rel.cpp:68
FloatRelType
Relation types for floats.
Definition float.hh:1068
@ FRT_LQ
Less or equal ( )
Definition float.hh:1071
@ FRT_GQ
Greater or equal ( )
Definition float.hh:1073
#define GECODE_MINIMODEL_EXPORT
Definition minimodel.hh:78
bool hasType(const LinFloatExpr &e, ArithNonLinFloatExpr::ArithNonLinFloatExprType t)
Check if e is of type t.
Gecode toplevel namespace
FloatVal operator/(const FloatVal &x, const FloatVal &y)
Definition val.hpp:213
void sin(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void sqr(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void cos(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void min(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
void abs(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void div(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
void mult(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
void sqrt(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void acos(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Post propagator for SetVar SetOpType SetVar y
Definition set.hh:767
void log(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void exp(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void atan(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
void asin(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void pow(Home home, FloatVar x0, int n, FloatVar x1)
Post propagator for for $n\geq 0$.
FloatVal operator*(const FloatVal &x, const FloatVal &y)
Definition val.hpp:200
Post propagator for SetVar x
Definition set.hh:767
void nroot(Home home, FloatVar x0, int n, FloatVar x1)
Post propagator for for $n\geq 0$.
void tan(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
#define GECODE_NEVER
Assert that this command is never executed.
Definition macros.hpp:56