Generated on Tue Apr 18 10:21:34 2017 for Gecode by doxygen 1.6.3

sqr-sqrt.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *     Guido Tack <tack@gecode.org>
00006  *     Vincent Barichard <Vincent.Barichard@univ-angers.fr>
00007  *
00008  *  Copyright:
00009  *     Christian Schulte, 2004
00010  *     Guido Tack, 2006
00011  *     Vincent Barichard, 2012
00012  *
00013  *  Last modified:
00014  *     $Date: 2017-04-10 13:21:37 +0200 (Mon, 10 Apr 2017) $ by $Author: schulte $
00015  *     $Revision: 15631 $
00016  *
00017  *  This file is part of Gecode, the generic constraint
00018  *  development environment:
00019  *     http://www.gecode.org
00020  *
00021  *  Permission is hereby granted, free of charge, to any person obtaining
00022  *  a copy of this software and associated documentation files (the
00023  *  "Software"), to deal in the Software without restriction, including
00024  *  without limitation the rights to use, copy, modify, merge, publish,
00025  *  distribute, sublicense, and/or sell copies of the Software, and to
00026  *  permit persons to whom the Software is furnished to do so, subject to
00027  *  the following conditions:
00028  *
00029  *  The above copyright notice and this permission notice shall be
00030  *  included in all copies or substantial portions of the Software.
00031  *
00032  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00033  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00034  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00035  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00036  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00037  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00038  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00039  *
00040  */
00041 
00042 namespace Gecode { namespace Float { namespace Arithmetic {
00043 
00044   /*
00045    * Positive bounds consistent squaring
00046    *
00047    */
00048   template<class VA, class VB>
00049   forceinline
00050   SqrPlus<VA,VB>::SqrPlus(Home home, VA x0, VB x1)
00051     : MixBinaryPropagator<VA,PC_FLOAT_BND,VB,PC_FLOAT_BND>(home,x0,x1) {}
00052 
00053   template<class VA, class VB>
00054   forceinline ExecStatus
00055   SqrPlus<VA,VB>::post(Home home, VA x0, VB x1) {
00056     if (same(x0,x1)) {
00057       if (x0.assigned())
00058         return ((x0.val() == 0) || (x0.val() == 1))? ES_OK : ES_FAILED;
00059     } else {
00060       GECODE_ME_CHECK(x0.eq(home,sqrt(x1.val())));
00061       GECODE_ME_CHECK(x1.eq(home,sqr(x0.val())));
00062     }
00063 
00064     (void) new (home) SqrPlus<VA,VB>(home,x0,x1);
00065     return ES_OK;
00066   }
00067 
00068   template<class VA, class VB>
00069   forceinline
00070   SqrPlus<VA,VB>::SqrPlus(Space& home, bool share, SqrPlus<VA,VB>& p)
00071     : MixBinaryPropagator<VA,PC_FLOAT_BND,VB,PC_FLOAT_BND>(home,share,p) {}
00072 
00073   template<class VA, class VB>
00074   Actor*
00075   SqrPlus<VA,VB>::copy(Space& home, bool share) {
00076     return new (home) SqrPlus<VA,VB>(home,share,*this);
00077   }
00078 
00079   template<class VA, class VB>
00080   ExecStatus
00081   SqrPlus<VA,VB>::propagate(Space& home, const ModEventDelta&) {
00082     if (same(x0,x1)) {
00083       if (x0.max() < 1) GECODE_ME_CHECK(x0.eq(home,0));
00084       else if (x0.min() > 0) GECODE_ME_CHECK(x0.eq(home,1));
00085       if (x0.assigned())
00086         return ((x0.val() == 0) || (x0.val() == 1))? home.ES_SUBSUMED(*this) : ES_FAILED;
00087     } else {
00088       GECODE_ME_CHECK(x0.eq(home,sqrt(x1.val())));
00089       GECODE_ME_CHECK(x1.eq(home,sqr(x0.val())));
00090       if (x0.assigned() || x1.assigned()) return home.ES_SUBSUMED(*this);
00091     }
00092 
00093     return ES_FIX;
00094   }
00095 
00096 
00097   /*
00098    * Bounds consistent squaring
00099    *
00100    */
00101 
00102   template<class View>
00103   forceinline
00104   Sqr<View>::Sqr(Home home, View x0, View x1)
00105     : BinaryPropagator<View,PC_FLOAT_BND>(home,x0,x1) {}
00106 
00107   template<class View>
00108   forceinline ExecStatus
00109   Sqr<View>::post(Home home, View x0, View x1) {
00110     GECODE_ME_CHECK(x1.gq(home,0));
00111     if (same(x0,x1)) {
00112       if (x0.assigned())
00113         return ((x0.val() == 0) || (x0.val() == 1))? ES_OK : ES_FAILED;
00114       GECODE_ME_CHECK(x1.lq(home,1));
00115       return SqrPlus<FloatView,FloatView>::post(home,x0,x1);
00116     } else {
00117       if (x0.min() >= 0)
00118         return SqrPlus<FloatView,FloatView>::post(home,x0,x1);
00119       if (x0.max() <= 0)
00120         return SqrPlus<MinusView,FloatView>::post(home,MinusView(x0),x1);
00121       GECODE_ME_CHECK(x1.eq(home,sqr(x0.val())));
00122       (void) new (home) Sqr<View>(home,x0,x1);
00123     }
00124     return ES_OK;
00125   }
00126 
00127   template<class View>
00128   forceinline
00129   Sqr<View>::Sqr(Space& home, bool share, Sqr<View>& p)
00130     : BinaryPropagator<View,PC_FLOAT_BND>(home,share,p) {}
00131 
00132   template<class View>
00133   Actor*
00134   Sqr<View>::copy(Space& home, bool share) {
00135     return new (home) Sqr<View>(home,share,*this);
00136   }
00137 
00138   template<class View>
00139   ExecStatus
00140   Sqr<View>::propagate(Space& home, const ModEventDelta&) {
00141     assert(x1.min() >= 0);
00142     if (x0.min() >= 0)
00143       GECODE_REWRITE(*this,(SqrPlus<FloatView,FloatView>::post(home(*this),x0,x1)));
00144     if (x0.max() <= 0)
00145       GECODE_REWRITE(*this,(SqrPlus<MinusView,FloatView>::post(home(*this),
00146         MinusView(x0),x1)));
00147 
00148     GECODE_ME_CHECK(x1.eq(home,sqr(x0.val())));
00149     Rounding r;
00150     FloatVal z = sqrt(x1.val());
00151     if (x0.min() > -r.sqrt_up(x1.min()))
00152       GECODE_ME_CHECK(x0.eq(home,z));
00153     else if (x0.max() < r.sqrt_down(x1.min()))
00154       GECODE_ME_CHECK(x0.eq(home,-z));
00155     else
00156       GECODE_ME_CHECK(x0.eq(home,hull(z,-z)));
00157 
00158     return ES_NOFIX;
00159   }
00160 
00161 
00162   /*
00163    * Bounds consistent square root operator
00164    *
00165    */
00166 
00167   template<class A, class B>
00168   forceinline
00169   Sqrt<A,B>::Sqrt(Home home, A x0, B x1)
00170     : MixBinaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND>(home,x0,x1) {}
00171 
00172   template<class A, class B>
00173   ExecStatus
00174   Sqrt<A,B>::post(Home home, A x0, B x1) {
00175     GECODE_ME_CHECK(x0.gq(home,0));
00176     if (same(x0,x1)) {
00177       if (x0.assigned())
00178         return ((x0.val() == 0) || (x0.val() == 1))? ES_OK : ES_FAILED;
00179       GECODE_ME_CHECK(x0.lq(home,1));
00180       (void) new (home) Sqrt<A,B>(home,x0,x1);
00181     } else {
00182       GECODE_ME_CHECK(x1.eq(home,sqrt(x0.val())));
00183       (void) new (home) Sqrt<A,B>(home,x0,x1);
00184     }
00185     return ES_OK;
00186   }
00187 
00188   template<class A, class B>
00189   forceinline
00190   Sqrt<A,B>::Sqrt(Space& home, bool share, Sqrt<A,B>& p)
00191     : MixBinaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND>(home,share,p) {}
00192 
00193   template<class A, class B>
00194   Actor*
00195   Sqrt<A,B>::copy(Space& home, bool share) {
00196     return new (home) Sqrt<A,B>(home,share,*this);
00197   }
00198 
00199   template<class A, class B>
00200   ExecStatus
00201   Sqrt<A,B>::propagate(Space& home, const ModEventDelta&) {
00202     if (same(x0,x1)) {
00203       if (x0.max() < 1) GECODE_ME_CHECK(x0.eq(home,0));
00204       else if (x0.min() > 0) GECODE_ME_CHECK(x0.eq(home,1));
00205       if (x0.assigned())
00206         return ((x0.val() == 0) || (x0.val() == 1))? home.ES_SUBSUMED(*this) : ES_FAILED;
00207     } else {
00208       GECODE_ME_CHECK(x0.eq(home,sqr(x1.val())));
00209       GECODE_ME_CHECK(x1.eq(home,sqrt(x0.val())));
00210       if (x0.assigned() || x1.assigned()) return home.ES_SUBSUMED(*this);
00211     }
00212 
00213     return ES_FIX;
00214   }
00215 
00216 }}}
00217 
00218 // STATISTICS: float-prop
00219