BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Root_of_2.h
Go to the documentation of this file.
00001 // Copyright (c) 2005,2006  INRIA Sophia-Antipolis (France)
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License as
00006 // published by the Free Software Foundation; version 2.1 of the License.
00007 // See the file LICENSE.LGPL distributed with CGAL.
00008 //
00009 // Licensees holding a valid commercial license may use this file in
00010 // accordance with the commercial license agreement provided with the software.
00011 //
00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 //
00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Number_types/include/CGAL/Root_of_2.h $
00016 // $Id: Root_of_2.h 50183 2009-06-29 16:16:33Z sloriot $
00017 //
00018 //
00019 // Author(s)     : Sylvain Pion, Monique Teillaud, Athanasios Kakargias, Pedro Machado
00020 
00021 #ifndef CGAL_ROOT_OF_2_H
00022 #define CGAL_ROOT_OF_2_H
00023 
00024 #include <iostream>
00025 #include <CGAL/number_type_basic.h>
00026 #include <CGAL/Root_of_traits.h>
00027 #include <CGAL/NT_converter.h>
00028 #include <CGAL/Kernel/mpl.h>
00029 #include <CGAL/enum.h>
00030 #include <CGAL/tags.h>
00031 #include <CGAL/Number_types/internal_functions_comparison_root_of_2.h>
00032 #include <CGAL/Interval_arithmetic.h>
00033 #include <CGAL/assertions.h>
00034 #include <boost/type_traits/is_same.hpp>
00035 
00036 #define CGAL_int(T)    typename First_if_different<int,    T>::Type
00037 #define CGAL_double(T) typename First_if_different<double, T>::Type
00038 
00039 namespace CGAL {
00040 
00041 // Number type representing a real root of a polynomial
00042 // of degree 1 or 2 over RT.
00043 //
00044 // It supports :
00045 // - constructor from degree 2 polynomial coefficients and a boolean
00046 // - constructor from degree 1 polynomial coefficients
00047 // - constructor from RT
00048 // - unary operator-()
00049 // - additions, subtractions, multiplications with an RT.
00050 // - additions, subtractions, multiplications with an RootOf_1.
00051 // - add +, -, *, / with 2 root_of_2 (when it is possible - same gamma)
00052 // - square()
00053 // - <, >, <=, >=, ==, != (symetric, mixed with RT, mixed with RootOf_1, mixed with int)
00054 // - compare()            (symetric, mixed with RT, mixed with RootOf_1, mixed with int)
00055 // - sign()
00056 // - to_double()
00057 // - to_interval()
00058 // - is_valid()
00059 // - operator[] to access the coefficients  (leading coeff is always positive)
00060 // - .conjuguate()
00061 // - .discriminant()
00062 // - .eval_at()
00063 // - .sign_at()
00064 // - .degree()
00065 // - .is_valid()
00066 // - operator<<()
00067 // - print() ("pretty" printing)
00068 // - make_root_of_2()
00069 // - add sqrt() (when it's degree 1), or a make_sqrt<RT>(const RT &r) ?
00070 // - inverse()
00071 // TODO :
00072 // - use Boost.Operators.
00073 // - add subtraction/addition with a degree 2 Root_of of the same field ?
00074 // - add constructor from Polynomial ?
00075 //   There should be a proper separate class Polynomial.
00076 // - in compare_roots, we evaluate the polynomial at some FT, or at some
00077 //   root of degree 1 polynomials.  It would be nice to have a separate
00078 //   polynomial class which performed this task (and others)...
00079 // - overloaded versions of make_root_of_2<>() for Lazy_exact_nt<> and others.
00080 
00081 template <class RT> struct Root_of_traits;
00082 
00083 template < typename RT_ >
00084 class Root_of_2 {
00085 
00086   // the value is the root of P(X) = C2.X^2 + C1.X + C0,
00087   // and C2 > 0.
00088 
00089 public:
00090 
00091   typedef RT_ RT;
00092   typedef typename Root_of_traits<RT>::RootOf_1 FT;
00093 
00094 private:
00095 
00096   FT  _alpha, _beta, _gamma;
00097   bool _rational;
00098 
00099 public:
00100 
00101 #ifdef CGAL_ROOT_OF_2_ENABLE_HISTOGRAM_OF_NUMBER_OF_DIGIT_ON_THE_COMPLEX_CONSTRUCTOR
00102   static int max_num_digit;
00103   static int histogram[10000];
00104 #endif
00105 
00106   Root_of_2()
00107     : _alpha(0), _rational(true)
00108   {
00109     CGAL_assertion(is_valid());
00110   }
00111 
00112   Root_of_2(const RT& c0)
00113     : _alpha(c0), _rational(true)
00114   {
00115     CGAL_assertion(is_valid());
00116   }
00117 
00118   Root_of_2(const typename First_if_different<int, RT>::Type & c0)
00119     : _alpha(RT(c0)), _rational(true)
00120   {
00121     CGAL_assertion(is_valid());
00122   }
00123 
00124   Root_of_2(const typename First_if_different<FT, RT>::Type & c0)
00125     : _alpha(c0), _rational(true)
00126   {
00127     CGAL_assertion(is_valid());
00128   }
00129 
00130   Root_of_2(const RT& a, const RT& b) {
00131     CGAL_assertion( b != 0 );
00132     _alpha = FT(a,b);
00133     _rational = true;
00134     CGAL_assertion(is_valid());
00135   }
00136 
00137   Root_of_2(const RT& a, const RT& b, const RT& c, const bool s)
00138   {
00139     if ( a != 0 ) {
00140       _alpha = FT(-b,2*a);
00141       _gamma = CGAL_NTS square(alpha()) - FT(c,a);
00142       if(CGAL_NTS is_zero(gamma())) {
00143         _rational = true;
00144       } else {
00145         _beta = (s ? -1 : 1);
00146         _rational = false;
00147       }
00148     }
00149     else {
00150       CGAL_assertion( b != 0 );
00151       _rational = true;
00152       _alpha = FT(-c,b);
00153       _beta = 0;
00154       _gamma = 0;
00155     }
00156     CGAL_assertion(is_valid());
00157   }
00158 
00159   Root_of_2(const typename First_if_different<FT, RT>::Type & c0,
00160             const typename First_if_different<FT, RT>::Type & c1,
00161             const typename First_if_different<FT, RT>::Type & c2)
00162   {
00163     if(CGAL_NTS is_zero(c1) || CGAL_NTS is_zero(c2)) {
00164       _alpha = c0;
00165       _rational = true;
00166 
00167 #ifdef CGAL_ROOT_OF_2_ENABLE_HISTOGRAM_OF_NUMBER_OF_DIGIT_ON_THE_COMPLEX_CONSTRUCTOR
00168       int n_a = c0.tam();
00169       if(max_num_digit < n_a) max_num_digit = n_a;
00170       histogram[n_a]++;
00171 #endif
00172 
00173     } else {
00174       _alpha = c0;
00175       _beta = c1;
00176       _gamma = c2;
00177       _rational = false;
00178 
00179 #ifdef CGAL_ROOT_OF_2_ENABLE_HISTOGRAM_OF_NUMBER_OF_DIGIT_ON_THE_COMPLEX_CONSTRUCTOR
00180       int n_a = c0.tam();
00181       int n_b = c1.tam();
00182       int n_c = c2.tam();
00183       if(max_num_digit < n_a) max_num_digit = n_a;
00184       if(max_num_digit < n_b) max_num_digit = n_b;
00185       if(max_num_digit < n_c) max_num_digit = n_c;
00186       histogram[n_a]++;
00187       histogram[n_b]++;
00188       histogram[n_c]++;
00189 #endif
00190 
00191     }
00192     CGAL_assertion(is_valid());
00193   }
00194 
00195   template <typename RT2>
00196   Root_of_2(const Root_of_2<RT2>& r)
00197     : _alpha(r.alpha()), _beta(r.beta()), _gamma(r.gamma()), _rational(r.is_rational())
00198   {
00199   }
00200 
00201   Root_of_2 operator-() const
00202   {
00203     if(is_rational()) return Root_of_2(-alpha());
00204     return Root_of_2 (-alpha(), -beta(), gamma());
00205   }
00206 
00207   bool is_valid() const
00208   {
00209     if(!is_rational()) {
00210       return gamma() >= 0;
00211     } return true;
00212   }
00213 
00214   bool is_rational() const
00215   {
00216     return _rational;
00217   }
00218 
00219   Root_of_2 inverse() const
00220   {
00221     CGAL_assertion(!(CGAL_NTS is_zero(alpha()) && (CGAL_NTS is_zero(beta()) || CGAL_NTS is_zero(gamma())))); // root = 0,
00222     FT r = (CGAL_NTS square(alpha())) -  (CGAL_NTS square(beta()))*gamma();
00223     CGAL_assertion(!(CGAL_NTS is_zero(r)
00224                    && (CGAL_NTS sign(beta()) != CGAL_NTS sign(alpha()))));
00225 // ex. 6 - 2 sqrt(9)
00226     if(CGAL_NTS is_zero(r)) return Root_of_2(1 / (2 * alpha()));
00227     else return Root_of_2(alpha()/r, -beta()/r, gamma());
00228   }
00229 
00230   Root_of_2 conjugate() const
00231   {
00232     if(is_rational()) return Root_of_2(alpha());
00233     return Root_of_2(alpha(),-beta(),gamma());
00234   }
00235 
00236   const FT& alpha() const
00237   {
00238     return _alpha;
00239   }
00240 
00241   const FT& beta() const
00242   {
00243     return _beta;
00244   }
00245 
00246   const FT& gamma() const
00247   {
00248     return _gamma;
00249   }
00250 
00251   bool is_smaller() const
00252   {
00253     return beta() <= 0;
00254   }
00255 
00256   // The following functions deal with the internal polynomial.
00257   // Probably they should move to a separate polynomial class.
00258 
00259   RT operator[](int i) const
00260   {
00261     typedef Rational_traits< FT > Rational;
00262     CGAL_assertion((i>=0) & (i<3));
00263     Rational r;
00264     const RT r1 = r.numerator(alpha());
00265     const RT d1 = r.denominator(alpha());
00266     const RT r2 = r.numerator(beta());
00267     const RT d2 = r.denominator(beta());
00268     const RT r3 = r.numerator(gamma());
00269     const RT d3 = r.denominator(gamma());
00270     if(i == 0) {
00271       return (CGAL_NTS square(d2)) * d3;
00272     }
00273     if(i == 1) {
00274       return -2 * (CGAL_NTS square(d2)) * d3 * r1;
00275     }
00276     // i == 2
00277     return ((CGAL_NTS square(d2)) * d3 * (CGAL_NTS square(r1))) -
00278            ((CGAL_NTS square(d1)) * r3 * (CGAL_NTS square(r2)));
00279 
00280   }
00281 
00282   RT discriminant() const
00283   {
00284     if(is_rational()) return RT(0);
00285     return CGAL_NTS square(operator[](1)) -
00286            4*(operator[](0))*(operator[](2));
00287   }
00288 
00289   template < typename T >
00290   T eval_at(const T& x) const
00291   {
00292     if(is_rational()) return x * (operator[](0)) - (operator[](1));
00293     if(CGAL_NTS is_zero(x)) return (operator[](2));
00294     const bool zeroC0 = CGAL_NTS is_zero((operator[](2)));
00295     const bool zeroC1 = CGAL_NTS is_zero((operator[](1)));
00296     if(zeroC0 && zeroC1) return x * (operator[](0));
00297     if(zeroC0) return x * ((operator[](1)) + x * (operator[](0)));
00298     if(zeroC1) return (x * x * (operator[](0))) + (operator[](2));
00299     return (operator[](2)) + x * ((operator[](1)) + x * (operator[](0)));
00300   }
00301 
00302   template < typename T >
00303   Sign sign_at(const T &x) const
00304   {
00305     // Maybe there is slightly more efficient.
00306     return CGAL_NTS sign(eval_at(x));
00307   }
00308 
00309 }; // Root_of_2
00310 
00311 // COERCION_TRAITS BEGIN
00312 
00313 CGAL_DEFINE_COERCION_TRAITS_FOR_SELF_TEM(Root_of_2<RT>,class RT)
00314 
00315 template <class RT>
00316 struct Coercion_traits< RT , Root_of_2<RT> >{
00317     typedef Tag_true  Are_explicit_interoperable;
00318     typedef Tag_true  Are_implicit_interoperable;
00319     typedef Root_of_2<RT> Type;
00320     struct Cast{
00321         typedef Type result_type;
00322         Type operator()(const Root_of_2<RT>& x)   const { return x;}
00323         Type operator()(const RT& x) const {
00324             return Type(x);}
00325     };
00326 };
00327 
00328 template <class RT>
00329 struct Coercion_traits< CGAL_int(RT) , Root_of_2<RT> >{
00330     typedef Tag_true  Are_explicit_interoperable;
00331     typedef Tag_true  Are_implicit_interoperable;
00332     typedef Root_of_2<RT> Type;
00333     struct Cast{
00334         typedef Type result_type;
00335         Type operator()(const Root_of_2<RT>& x)   const { return x;}
00336         Type operator()(CGAL_int(RT) x) const {
00337             return Type(x);}
00338     };
00339 };
00340 
00341 template <class RT>
00342 struct Coercion_traits< typename Root_of_traits<RT>::RootOf_1 , Root_of_2<RT> >{
00343     typedef Tag_true  Are_explicit_interoperable;
00344     typedef Tag_true  Are_implicit_interoperable;
00345     typedef Root_of_2<RT> Type;
00346     struct Cast{
00347         typedef Type result_type;
00348         Type operator()(const Root_of_2<RT>& x)   const { return x;}
00349         Type operator()(const RT& x) const {
00350             return Type(x);}
00351     };
00352 };
00353 
00354 
00355 template <class RT, class NTX >
00356 struct Coercion_traits< Root_of_2<RT> , NTX  >
00357     :public Coercion_traits<NTX , Root_of_2<RT> >{};
00358 
00359 // COERCION_TRAITS END
00360 
00361 #ifdef CGAL_ROOT_OF_2_ENABLE_HISTOGRAM_OF_NUMBER_OF_DIGIT_ON_THE_COMPLEX_CONSTRUCTOR
00362 
00363 template < typename RT_ >
00364 int Root_of_2<RT_>::max_num_digit = 0;
00365 
00366 template < typename RT_ >
00367 int Root_of_2<RT_>::histogram[10000];
00368 
00369 #endif
00370 
00371 
00372 template < class NT1,class NT2 >
00373 struct NT_converter < Root_of_2<NT1> , Root_of_2<NT2> >
00374   : public std::unary_function< NT1, NT2 >
00375 {
00376     Root_of_2<NT2>
00377     operator()(const Root_of_2<NT1> &a) const
00378     {
00379       if(a.is_rational()) {
00380         return Root_of_2<NT2>(NT_converter<NT1,NT2>()(a.alpha()));
00381       } else {
00382         return Root_of_2<NT2>(NT_converter<NT1,NT2>()(a.alpha()),
00383                               NT_converter<NT1,NT2>()(a.beta()),
00384                               NT_converter<NT1,NT2>()(a.gamma()));
00385       }
00386     }
00387 };
00388 
00389 template < class NT1,class NT2 >
00390 struct NT_converter < NT1 , Root_of_2<NT2> >
00391   : public std::unary_function< NT1, NT2 >
00392 {
00393     Root_of_2<NT2>
00394     operator()(const NT1 &a) const
00395     {
00396         return Root_of_2<NT2>(NT_converter<NT1,NT2>()(a));
00397     }
00398 };
00399 
00400 template < class NT1 >
00401 struct NT_converter < Root_of_2<NT1>, Root_of_2<NT1> >
00402   : public std::unary_function< NT1, NT1 >
00403 {
00404     const Root_of_2<NT1> &
00405     operator()(const Root_of_2<NT1> &a) const
00406     {
00407         return a;
00408     }
00409 };
00410 
00411 template <class RT>
00412 class Algebraic_structure_traits<Root_of_2<RT> >
00413     :public Algebraic_structure_traits_base<Root_of_2<RT> , Null_tag >{
00414 public:
00415 
00416     typedef Root_of_2<RT> Type;
00417     typedef typename Algebraic_structure_traits<RT>::Is_exact Is_exact;
00418     struct Square
00419         : public std::unary_function< Root_of_2<RT> , Root_of_2<RT> >{
00420         Root_of_2<RT> operator()(const Root_of_2<RT>& a){
00421 
00422             CGAL_assertion(is_valid(a));
00423 
00424             if(a.is_rational()) {
00425                 return Root_of_2<RT>(CGAL_NTS square(a.alpha()));
00426             }
00427 
00428             // It's easy to get the explicit formulas for the square of the two roots.
00429             // Then it's easy to compute their sum and their product, which gives the
00430             // coefficients of the polynomial (X^2 - Sum X + Product).
00431             return Root_of_2<RT> ( CGAL_NTS square(a.alpha()) +
00432                     (CGAL_NTS square(a.beta())) * a.gamma(),
00433                     2 * a.alpha() * a.beta(),
00434                     a.gamma());
00435         }
00436     };
00437 };
00438 
00439 
00440 template<class RT>
00441 class Real_embeddable_traits<Root_of_2<RT> >
00442     :public INTERN_RET::Real_embeddable_traits_base<Root_of_2<RT> , CGAL::Tag_true >{
00443     typedef Real_embeddable_traits<RT> RET_RT;
00444     typedef typename Root_of_traits<RT>::RootOf_1 Root_of_1;
00445 public:
00446     typedef Root_of_2<RT> Type;
00447     typedef Tag_true Is_real_embeddable;
00448 
00449     class Abs
00450         : public std::unary_function< Type, Type >{
00451     public:
00452         Type operator()(const Type& x) const {
00453             return (x>=0)?x:-x;
00454         }
00455     };
00456 
00457     class Sgn
00458         : public std::unary_function< Type, ::CGAL::Sign >{
00459     public:
00460         ::CGAL::Sign operator()(const Type& a) const {
00461             const ::CGAL::Sign sign_alpha = CGAL_NTS sign(a.alpha());
00462             if (a.is_rational()) return (sign_alpha);
00463             // If alpha and beta have the same sign, return this sign.
00464             const ::CGAL::Sign sign_beta = CGAL_NTS sign (a.beta());
00465             if (sign_alpha == sign_beta) return (sign_alpha);
00466             if (sign_alpha == ZERO) return (sign_beta);
00467 
00468             // Compare the squared values of m_alpha and of m_beta*sqrt(m_gamma):
00469             const Comparison_result res = CGAL_NTS compare (CGAL_NTS square(a.alpha()),
00470                     CGAL_NTS square(a.beta()) * a.gamma());
00471             if (res == LARGER) return sign_alpha;
00472             else if (res == SMALLER) return sign_beta;
00473             else return ZERO;
00474         }
00475     };
00476 
00477     class Compare
00478         : public std::binary_function< Type,
00479                                   Type,
00480                                   Comparison_result >{
00481     public:
00482         Comparison_result operator()(
00483                 const Type& a,
00484                 const Type& b) const{
00485             typedef typename Root_of_traits< RT >::RootOf_1 FT;
00486             typedef typename First_if_different<FT, RT>::Type WhatType;
00487             typedef typename boost::is_same< WhatType, RT > do_not_filter;
00488 
00489             CGAL_assertion(is_valid(a) & is_valid(b));
00490 
00491             if (a.is_rational()) return (CGAL_NTS compare(a.alpha(), b));
00492             if (b.is_rational()) return (CGAL_NTS compare(a, b.alpha()));
00493 
00494             if(!do_not_filter::value) {
00495                 Interval_nt<> ia = CGAL_NTS to_interval(a);
00496                 Interval_nt<> ib = CGAL_NTS to_interval(b);
00497                 if(ia.inf() > ib.sup()) return LARGER;
00498                 if(ia.sup() < ib.inf()) return SMALLER;
00499             }
00500 
00501             // Perform the exact comparison:
00502             // Note that the comparison of (a1 + b1*sqrt(c1)) and (a2 + b2*sqrt(c2))
00503             // is equivalent to comparing (a1 - a2) and (b2*sqrt(c2) -  b1*sqrt(c1)).
00504             // We first determine the signs of these terms.
00505             const FT diff_alpha = a.alpha() - b.alpha();
00506             const ::CGAL::Sign sign_left = CGAL_NTS sign(diff_alpha);
00507             const FT a_sqr = a.beta()*a.beta()*a.gamma();
00508             const FT b_sqr = b.beta()*b.beta()*b.gamma();
00509             Comparison_result right_res = CGAL_NTS compare (b_sqr, a_sqr);
00510             ::CGAL::Sign sign_right = ZERO;
00511 
00512             if (right_res == LARGER)
00513                 {
00514                     // Take the sign of b2:
00515                     sign_right = CGAL_NTS sign(b.beta());
00516                 }
00517             else if (right_res == SMALLER)
00518                 {
00519                     // Take the opposite sign of b1:
00520                     switch (CGAL_NTS sign (a.beta()))
00521                         {
00522                         case POSITIVE :
00523                             sign_right = NEGATIVE;
00524                             break;
00525                         case NEGATIVE:
00526                             sign_right = POSITIVE;
00527                             break;
00528                         case ZERO:
00529                             sign_right = ZERO;
00530                             break;
00531                         default:
00532                             // We should never reach here.
00533                             CGAL_error();
00534                         }
00535                 }
00536             else
00537                 {
00538                     // We take the sign of (b2*sqrt(c2) -  b1*sqrt(c1)), where both terms
00539                     // have the same absolute value. The sign is equal to the sign of b2,
00540                     // unless both terms have the same sign, so the whole expression is 0.
00541                     sign_right = CGAL_NTS sign (b.beta());
00542                     if (sign_right == CGAL_NTS sign (a.beta()))
00543                         sign_right = ZERO;
00544                 }
00545 
00546             // Check whether on of the terms is zero. In this case, the comparsion
00547             // result is simpler:
00548             if (sign_left == ZERO)
00549                 {
00550                     if (sign_right == POSITIVE)
00551                         return (SMALLER);
00552                     else if (sign_right == NEGATIVE)
00553                         return (LARGER);
00554                     else
00555                         return (EQUAL);
00556                 }
00557             else if (sign_right == ZERO)
00558                 {
00559                     if (sign_left == POSITIVE)
00560                         return (LARGER);
00561                     else if (sign_left == NEGATIVE)
00562                         return (SMALLER);
00563                     else
00564                         return (EQUAL);
00565                 }
00566 
00567             // If the signs are not equal, we can determine the comparison result:
00568             if (sign_left != sign_right)
00569                 {
00570                     if (sign_left == POSITIVE)
00571                         return (LARGER);
00572                     else
00573                         return (SMALLER);
00574                 }
00575 
00576             // We now square both terms and look at the sign of the one-root number:
00577             //   ((a1 - a2)^2 - (b1^2*c1 + b2^2*c2)) + 2*b1*b2*sqrt(c1*c2)
00578             //
00579             // If both signs are negative, we should swap the comparsion result
00580             // we eventually compute.
00581             const FT A = diff_alpha*diff_alpha - (a_sqr + b_sqr);
00582             const FT B = 2 * a.beta() * b.beta();
00583             const FT C = a.gamma() * b.gamma();
00584             const ::CGAL::Sign sgn = CGAL_NTS sign(Root_of_2<RT>(A, B, C));
00585             const bool swap_res = (sign_left == NEGATIVE);
00586 
00587             if (sgn == POSITIVE)
00588                 return (swap_res ? SMALLER : LARGER);
00589             else if (sgn == NEGATIVE)
00590                 return (swap_res ? LARGER : SMALLER);
00591             else
00592                 return (EQUAL);
00593         }
00594 
00595         Comparison_result
00596         inline
00597         operator()(
00598                 const Type& a,
00599                 const Root_of_1& b
00600         ) const{
00601             typedef typename Root_of_traits< RT >::RootOf_1 FT;
00602             typedef typename First_if_different<FT, RT>::Type WhatType;
00603             typedef typename boost::is_same< WhatType, RT > do_not_filter;
00604 
00605             CGAL_assertion(is_valid(a) & is_valid(b));
00606 
00607             if (a.is_rational()) return (CGAL_NTS compare (a.alpha(), b));
00608 
00609             if(!do_not_filter::value) {
00610                 Interval_nt<> ia = CGAL_NTS to_interval(a);
00611                 Interval_nt<> ib = CGAL_NTS to_interval(b);
00612                 if(ia.inf() > ib.sup()) return LARGER;
00613                 if(ia.sup() < ib.inf()) return SMALLER;
00614             }
00615 
00616             // Perform the exact comparison.
00617             const ::CGAL::Sign   sgn = CGAL_NTS  sign(a - b);
00618             if (sgn == POSITIVE) return (LARGER);
00619             else if (sgn == NEGATIVE) return (SMALLER);
00620             else return (EQUAL);
00621         }
00622 
00623         Comparison_result
00624         inline
00625         operator()(
00626                 const Root_of_1& a,
00627                 const Type& b
00628         ) const{ return opposite(this->operator()(b,a) ); }
00629 
00630         Comparison_result
00631         inline
00632         operator()(
00633                 const Type& a,
00634                 const RT& b
00635         ) const{
00636             typedef typename Root_of_traits< RT >::RootOf_1 FT;
00637             typedef typename First_if_different<FT, RT>::Type WhatType;
00638             typedef typename boost::is_same< WhatType, RT > do_not_filter;
00639 
00640             CGAL_assertion(is_valid(a) & is_valid(b));
00641 
00642             if (a.is_rational()) return (CGAL_NTS compare (a.alpha(), b));
00643 
00644             if(!do_not_filter::value) {
00645                 Interval_nt<> ia = CGAL_NTS to_interval(a);
00646                 Interval_nt<> ib = CGAL_NTS to_interval(b);
00647                 if(ia.inf() > ib.sup()) return LARGER;
00648                 if(ia.sup() < ib.inf()) return SMALLER;
00649             }
00650 
00651             // Perform the exact comparison.
00652             const ::CGAL::Sign   sgn = CGAL_NTS sign(a - b);
00653             if (sgn == POSITIVE) return (LARGER);
00654             else if (sgn == NEGATIVE) return (SMALLER);
00655             else return (EQUAL);
00656         }
00657 
00658         inline
00659         Comparison_result
00660         operator()(const RT &a, const Root_of_2<RT> &b)
00661         {
00662             return opposite(this->operator()(b, a));
00663         }
00664 
00665         inline
00666         Comparison_result
00667         operator()( CGAL_int(RT)  a, const Root_of_2<RT> &b)
00668         {
00669             return this->operator()(RT(a),b);
00670         }
00671 
00672         inline
00673         Comparison_result
00674         operator()(const Root_of_2<RT> &a, CGAL_int(RT) b)
00675         {
00676             return this->operator()(a,RT(b));
00677         }
00678     };
00679 
00680     class To_double
00681         : public std::unary_function< Type, double >{
00682     public:
00683         double operator()(const Type& x) const {
00684             if (x.is_rational()) {
00685                                 return (CGAL_NTS to_double(x.alpha()));
00686                               }
00687             return CGAL_NTS to_double(x.alpha()) +
00688                    CGAL_NTS to_double(x.beta()) *
00689                    (std::sqrt)(CGAL_NTS to_double(x.gamma()));
00690         }
00691     };
00692 
00693     class To_interval
00694         : public std::unary_function< Type, std::pair< double, double > >{
00695     public:
00696         std::pair<double,double> operator()(const Type& x) const {
00697 
00698             if(x.is_rational()) return CGAL_NTS to_interval(x.alpha());
00699 
00700             const Interval_nt<true>   alpha_in
00701                 = CGAL_NTS to_interval(x.alpha());
00702             const Interval_nt<true>   beta_in
00703                 = CGAL_NTS to_interval(x.beta());
00704             const Interval_nt<true>   gamma_in
00705                 = CGAL_NTS to_interval(x.gamma());
00706             const Interval_nt<true>&  x_in = alpha_in +
00707                 (beta_in * CGAL_NTS sqrt(gamma_in));
00708             return x_in.pair();
00709         }
00710     };
00711 };
00712 
00713 template < typename RT > inline
00714 bool operator<(const Root_of_2<RT> &a, const Root_of_2<RT> &b) {
00715   return CGAL_NTS compare(a, b) < 0;
00716 }
00717 
00718 template < typename RT > inline
00719 bool operator<(const typename Root_of_traits< RT >::RootOf_1 &a,
00720           const Root_of_2<RT> &b)
00721 {
00722   return CGAL_NTS compare(a, b) < 0;
00723 }
00724 
00725 template < typename RT > inline
00726 bool operator<(const Root_of_2<RT> &a,
00727           const typename Root_of_traits< RT >::RootOf_1 &b)
00728 {
00729   return CGAL_NTS compare(a, b) < 0;
00730 }
00731 
00732 template < typename RT > inline
00733 bool operator<(const RT &a, const Root_of_2<RT> &b)
00734 {
00735   return CGAL_NTS compare(a, b) < 0;
00736 }
00737 
00738 template < typename RT > inline
00739 bool operator<(const Root_of_2<RT> &a, const RT &b)
00740 {
00741   return CGAL_NTS compare(a, b) < 0;
00742 }
00743 
00744 template < typename RT > inline
00745 bool operator<(const CGAL_int(RT) &a, const Root_of_2<RT> &b)
00746 {
00747   return CGAL_NTS compare(a, b) < 0;
00748 }
00749 
00750 template < typename RT > inline
00751 bool operator<(const Root_of_2<RT> &a, const CGAL_int(RT) &b)
00752 {
00753   return CGAL_NTS compare(a, b) < 0;
00754 }
00755 
00756 template < typename RT > inline
00757 bool operator>(const Root_of_2<RT> &a, const Root_of_2<RT> &b)
00758 {
00759   return b < a;
00760 }
00761 
00762 template < typename RT > inline
00763 bool operator>(const typename Root_of_traits< RT >::RootOf_1 &a,
00764           const Root_of_2<RT> &b)
00765 {
00766   return b < a;
00767 }
00768 
00769 template < typename RT > inline
00770 bool operator>(const Root_of_2<RT> &a,
00771           const typename Root_of_traits< RT >::RootOf_1 &b)
00772 {
00773   return b < a;
00774 }
00775 
00776 template < typename RT > inline
00777 bool operator>(const RT &a, const Root_of_2<RT> &b)
00778 {
00779   return b < a;
00780 }
00781 
00782 template < typename RT > inline
00783 bool operator>(const Root_of_2<RT> &a, const RT &b)
00784 {
00785   return b < a;
00786 }
00787 
00788 template < typename RT > inline
00789 bool operator>(const CGAL_int(RT) &a, const Root_of_2<RT> &b)
00790 {
00791   return b < a;
00792 }
00793 
00794 template < typename RT > inline
00795 bool operator>(const Root_of_2<RT> &a, const CGAL_int(RT) &b)
00796 {
00797   return b < a;
00798 }
00799 
00800 template < typename RT > inline
00801 bool operator>=(const Root_of_2<RT> &a, const Root_of_2<RT> &b)
00802 {
00803   return !(a < b);
00804 }
00805 
00806 template < typename RT > inline
00807 bool operator>=(const typename Root_of_traits< RT >::RootOf_1 &a,
00808            const Root_of_2<RT> &b)
00809 {
00810   return !(a < b);
00811 }
00812 
00813 template < typename RT > inline
00814 bool operator>=(const Root_of_2<RT> &a,
00815            const typename Root_of_traits< RT >::RootOf_1 &b)
00816 {
00817   return !(a < b);
00818 }
00819 
00820 template < typename RT > inline
00821 bool operator>=(const RT &a, const Root_of_2<RT> &b)
00822 {
00823   return !(a < b);
00824 }
00825 
00826 template < typename RT > inline
00827 bool operator>=(const Root_of_2<RT> &a, const RT &b)
00828 {
00829   return !(a < b);
00830 }
00831 
00832 template < typename RT > inline
00833 bool operator>=(const CGAL_int(RT) &a, const Root_of_2<RT> &b)
00834 {
00835   return !(a < b);
00836 }
00837 
00838 template < typename RT > inline
00839 bool operator>=(const Root_of_2<RT> &a, const CGAL_int(RT) &b)
00840 {
00841   return !(a < b);
00842 }
00843 
00844 template < typename RT > inline
00845 bool operator<=(const Root_of_2<RT> &a, const Root_of_2<RT> &b)
00846 {
00847   return !(a > b);
00848 }
00849 
00850 template < typename RT > inline
00851 bool operator<=(const typename Root_of_traits< RT >::RootOf_1 &a,
00852            const Root_of_2<RT> &b)
00853 {
00854   return !(a > b);
00855 }
00856 
00857 template < typename RT > inline
00858 bool operator<=(const Root_of_2<RT> &a,
00859            const typename Root_of_traits< RT >::RootOf_1 &b)
00860 {
00861   return !(a > b);
00862 }
00863 
00864 template < typename RT > inline
00865 bool operator<=(const RT &a, const Root_of_2<RT> &b)
00866 {
00867   return !(a > b);
00868 }
00869 
00870 template < typename RT > inline
00871 bool operator<=(const Root_of_2<RT> &a, const RT &b)
00872 {
00873   return !(a > b);
00874 }
00875 
00876 template < typename RT > inline
00877 bool operator<=(const CGAL_int(RT) &a, const Root_of_2<RT> &b)
00878 {
00879   return !(a > b);
00880 }
00881 
00882 template < typename RT > inline
00883 bool operator<=(const Root_of_2<RT> &a, const CGAL_int(RT) &b)
00884 {
00885   return !(a > b);
00886 }
00887 
00888 template < typename RT > inline
00889 bool operator==(const Root_of_2<RT> &a, const Root_of_2<RT> &b)
00890 {
00891   return CGAL_NTS compare(a, b) == 0;
00892 }
00893 
00894 template < typename RT > inline
00895 bool operator==(const typename Root_of_traits< RT >::RootOf_1 &a,
00896            const Root_of_2<RT> &b)
00897 {
00898   return CGAL_NTS compare(a, b) == 0;
00899 }
00900 
00901 template < typename RT > inline
00902 bool operator==(const Root_of_2<RT> &a,
00903            const typename Root_of_traits< RT >::RootOf_1 &b)
00904 {
00905   return CGAL_NTS compare(a, b) == 0;
00906 }
00907 
00908 template < typename RT > inline
00909 bool operator==(const RT &a, const Root_of_2<RT> &b)
00910 {
00911   return CGAL_NTS compare(a, b) == 0;
00912 }
00913 
00914 template < typename RT > inline
00915 bool operator==(const Root_of_2<RT> &a, const RT &b)
00916 {
00917   return CGAL_NTS compare(a, b) == 0;
00918 }
00919 
00920 template < typename RT > inline
00921 bool operator==(const CGAL_int(RT) &a, const Root_of_2<RT> &b)
00922 {
00923   return CGAL_NTS compare(a, b) == 0;
00924 }
00925 
00926 template < typename RT > inline
00927 bool operator==(const Root_of_2<RT> &a, const CGAL_int(RT) &b)
00928 {
00929   return CGAL_NTS compare(a, b) == 0;
00930 }
00931 
00932 template < typename RT > inline
00933 bool operator!=(const Root_of_2<RT> &a, const Root_of_2<RT> &b)
00934 {
00935   return !(a == b);
00936 }
00937 
00938 template < typename RT > inline
00939 bool operator!=(const typename Root_of_traits< RT >::RootOf_1 &a,
00940            const Root_of_2<RT> &b)
00941 {
00942   return !(a == b);
00943 }
00944 
00945 template < typename RT > inline
00946 bool operator!=(const Root_of_2<RT> &a,
00947            const typename Root_of_traits< RT >::RootOf_1 &b)
00948 {
00949   return !(a == b);
00950 }
00951 
00952 template < typename RT > inline
00953 bool operator!=(const RT &a, const Root_of_2<RT> &b)
00954 {
00955   return !(a == b);
00956 }
00957 
00958 template < typename RT > inline
00959 bool operator!=(const Root_of_2<RT> &a, const RT &b)
00960 {
00961   return !(a == b);
00962 }
00963 
00964 template < typename RT > inline
00965 bool operator!=(const CGAL_int(RT) &a, const Root_of_2<RT> &b)
00966 {
00967   return !(a == b);
00968 }
00969 
00970 template < typename RT > inline
00971 bool operator!=(const Root_of_2<RT> &a, const CGAL_int(RT) &b)
00972 {
00973   return !(a == b);
00974 }
00975 
00976 // END OF COMPARISON OPERATORS
00977 
00978 template < typename RT >
00979 Root_of_2<RT> inverse(const Root_of_2<RT> &a)
00980 {
00981   CGAL_assertion(is_valid(a));
00982   return a.inverse();
00983 }
00984 
00985 template < typename RT >
00986 Root_of_2<RT> make_sqrt(const RT& r)
00987 {
00988   CGAL_assertion(r >= 0);
00989   if(CGAL_NTS is_zero(r)) return Root_of_2<RT>();
00990   return Root_of_2<RT>(0,1,r);
00991 }
00992 
00993 template < typename RT >
00994 Root_of_2<RT> make_sqrt(const typename Root_of_traits< RT >::RootOf_1& r)
00995 {
00996   CGAL_assertion(r >= 0);
00997   if(CGAL_NTS is_zero(r)) return Root_of_2<RT>();
00998   return Root_of_2<RT>(0,1,r);
00999 }
01000 
01001 
01002 template < typename RT >
01003 Root_of_2<RT>
01004 operator-(const Root_of_2<RT> &a,
01005           const typename Root_of_traits< RT >::RootOf_1& b)
01006 {
01007   typedef typename Root_of_traits< RT >::RootOf_1  RootOf_1;
01008   typedef Rational_traits< RootOf_1 >        Rational;
01009   //RT should be the same as Rational::RT
01010 
01011   CGAL_assertion(is_valid(a) & is_valid(b));
01012 
01013   if(a.is_rational()) {
01014     return Root_of_2<RT>(a.alpha() - b);
01015   }
01016 
01017   return Root_of_2<RT>(a.alpha() - b, a.beta(), a.gamma());
01018 }
01019 
01020 template < typename RT >
01021 inline
01022 Root_of_2<RT>
01023 operator-(const typename Root_of_traits< RT >::RootOf_1 &a,
01024           const Root_of_2<RT> &b)
01025 {
01026   return -(b-a);
01027 }
01028 
01029 template < typename RT >
01030 Root_of_2<RT>
01031 operator-(const Root_of_2<RT> &a, const RT& b)
01032 {
01033   typedef typename Root_of_traits< RT >::RootOf_1  RootOf_1;
01034   typedef Rational_traits< RootOf_1 >        Rational;
01035   //RT should be the same as Rational::RT
01036 
01037   CGAL_assertion(is_valid(a) & is_valid(b));
01038 
01039   if(a.is_rational()) {
01040     return Root_of_2<RT>(a.alpha() - b);
01041   }
01042 
01043   return Root_of_2<RT>(a.alpha() - b, a.beta(), a.gamma());
01044 }
01045 
01046 template < typename RT > inline
01047 Root_of_2<RT> operator-(const Root_of_2<RT> &a, const CGAL_int(RT)& b)
01048 {
01049   return (a-RT(b));
01050 }
01051 
01052 template < typename RT > inline
01053 Root_of_2<RT> operator-(const RT &a, const Root_of_2<RT> &b)
01054 {
01055   return (-(b-a));
01056 }
01057 
01058 template < typename RT > inline
01059 Root_of_2<RT> operator-(const CGAL_int(RT)& a, const Root_of_2<RT> &b)
01060 {
01061   return (-(b-RT(a)));
01062 }
01063 
01064 template < typename RT > inline
01065 Root_of_2<RT> operator+(const Root_of_2<RT> &a,
01066           const typename Root_of_traits< RT >::RootOf_1& b)
01067 {
01068   return a - typename Root_of_traits< RT >::RootOf_1(-b);
01069 }
01070 
01071 template < typename RT > inline
01072 Root_of_2<RT> operator+(const typename Root_of_traits< RT >::RootOf_1 &a,
01073           const Root_of_2<RT> &b)
01074 {
01075   return b - typename Root_of_traits< RT >::RootOf_1(-a);
01076 }
01077 
01078 template < typename RT > inline
01079 Root_of_2<RT> operator+(const Root_of_2<RT> &a, const RT& b)
01080 {
01081   return a - RT(-b);
01082 }
01083 
01084 template < typename RT > inline
01085 Root_of_2<RT> operator+(const Root_of_2<RT> &a, const CGAL_int(RT)& b)
01086 {
01087   return a - RT(-b);
01088 }
01089 
01090 template < typename RT > inline
01091 Root_of_2<RT> operator+(const RT &a, const Root_of_2<RT> &b)
01092 {
01093   return b - RT(-a);
01094 }
01095 
01096 template < typename RT > inline
01097 Root_of_2<RT> operator+(const CGAL_int(RT) &a, const Root_of_2<RT> &b)
01098 {
01099   return b - RT(-a);
01100 }
01101 
01102 template < typename RT >
01103 Root_of_2<RT>
01104 operator*(const Root_of_2<RT> &a,
01105           const typename Root_of_traits< RT >::RootOf_1& b)
01106 {
01107   typedef typename Root_of_traits< RT >::RootOf_1  RootOf_1;
01108   typedef Rational_traits< RootOf_1 >        Rational;
01109   //RT should be the same as Rational::RT
01110 
01111   CGAL_assertion(is_valid(a) & is_valid(b));
01112 
01113   if(CGAL_NTS is_zero(b)) return Root_of_2<RT>();
01114 
01115   if(a.is_rational()) {
01116     return Root_of_2<RT>(a.alpha() * b);
01117   }
01118 
01119   return Root_of_2<RT>(a.alpha() * b,
01120                        a.beta() * b,
01121                        a.gamma());
01122 }
01123 
01124 template < typename RT >
01125 inline
01126 Root_of_2<RT>
01127 operator*(const typename Root_of_traits< RT >::RootOf_1 &a,
01128           const Root_of_2<RT> &b)
01129 {
01130   return b * a;
01131 }
01132 
01133 template < typename RT >
01134 Root_of_2<RT>
01135 operator*(const Root_of_2<RT> &a, const RT& b)
01136 {
01137   typedef typename Root_of_traits< RT >::RootOf_1  RootOf_1;
01138   typedef Rational_traits< RootOf_1 >        Rational;
01139   //RT should be the same as Rational::RT
01140 
01141   CGAL_assertion(is_valid(a) & is_valid(b));
01142 
01143   if(CGAL_NTS is_zero(b)) return Root_of_2<RT>();
01144 
01145   if(a.is_rational()) {
01146     return Root_of_2<RT>(a.alpha() * b);
01147   }
01148 
01149   return Root_of_2<RT>(a.alpha() * b,
01150                        a.beta() * b,
01151                        a.gamma());
01152 }
01153 
01154 template < typename RT > inline
01155 Root_of_2<RT> operator*(const Root_of_2<RT> &a, const CGAL_int(RT)& b)
01156 {
01157   return a * RT(b);
01158 }
01159 
01160 template < typename RT > inline
01161 Root_of_2<RT> operator*(const RT &a, const Root_of_2<RT> &b)
01162 {
01163   return b * a;
01164 }
01165 
01166 template < typename RT > inline
01167 Root_of_2<RT> operator*(const CGAL_int(RT) &a, const Root_of_2<RT> &b)
01168 {
01169   return b * RT(a);
01170 }
01171 
01172 template < typename RT >
01173 Root_of_2<RT>
01174 operator/(const Root_of_2<RT> &a, const RT& b)
01175 {
01176   typedef typename Root_of_traits< RT >::RootOf_1  RootOf_1;
01177 
01178   CGAL_assertion(b != 0);
01179   CGAL_assertion(is_valid(a));
01180 
01181   if(a.is_rational()) {
01182     return Root_of_2<RT>(a.alpha() / b);
01183   }
01184 
01185   return Root_of_2<RT>(a.alpha()/b,
01186                        a.beta()/b,
01187                        a.gamma());
01188 }
01189 
01190 template < typename RT > inline
01191 Root_of_2<RT> operator/(const Root_of_2<RT> &a, const CGAL_int(RT)& b)
01192 {
01193   return a / RT(b);
01194 }
01195 
01196 template < typename RT > inline
01197 Root_of_2<RT> operator/(const RT& a, const Root_of_2<RT> &b)
01198 {
01199   return b.inverse() * a;
01200 }
01201 
01202 template < typename RT > inline
01203 Root_of_2<RT> operator/(const CGAL_int(RT)& a, const Root_of_2<RT> &b)
01204 {
01205   return b.inverse() * RT(a);
01206 }
01207 
01208 template < typename RT >
01209 Root_of_2<RT>
01210 operator/(const Root_of_2<RT> &a,
01211           const typename Root_of_traits< RT >::RootOf_1& b)
01212 {
01213   typedef typename Root_of_traits< RT >::RootOf_1  RootOf_1;
01214 
01215   CGAL_assertion(b != 0);
01216   CGAL_assertion(is_valid(a));
01217 
01218   if(a.is_rational()) {
01219     return Root_of_2<RT>(a.alpha() / b);
01220   }
01221 
01222   return Root_of_2<RT>(a.alpha()/b,
01223                        a.beta()/b,
01224                        a.gamma());
01225 }
01226 
01227 template < typename RT > inline
01228 Root_of_2<RT> operator/(const typename Root_of_traits< RT >::RootOf_1& a,
01229           const Root_of_2<RT> &b)
01230 {
01231   return b.inverse() * a;
01232 }
01233 
01234 template < typename RT >
01235 Root_of_2<RT>
01236 operator-(const Root_of_2<RT> &a,
01237           const Root_of_2<RT> &b)
01238 {
01239 
01240   CGAL_assertion(is_valid(a));
01241   CGAL_assertion(is_valid(b));
01242   CGAL_assertion((a.is_rational() || b.is_rational()) || (a.gamma() == b.gamma()));
01243 
01244   if(a.is_rational() && b.is_rational()) {
01245     return Root_of_2<RT>(a.alpha() - b.alpha());
01246   }
01247   if(a.is_rational()) return a.alpha() - b;
01248   if(b.is_rational()) return a - b.alpha();
01249 
01250   if(a.beta() == b.beta()) {
01251     return Root_of_2<RT>(a.alpha() - b.alpha());
01252   }
01253 
01254   return Root_of_2<RT>(a.alpha() - b.alpha(),
01255                        a.beta() - b.beta(),
01256                        a.gamma());
01257 }
01258 
01259 template < typename RT > inline
01260 Root_of_2<RT> operator+(const Root_of_2<RT> &a, const Root_of_2<RT> &b)
01261 {
01262   return b - (-a);
01263 }
01264 
01265 template < typename RT >
01266 Root_of_2<RT>
01267 operator*(const Root_of_2<RT> &a,
01268           const Root_of_2<RT> &b)
01269 {
01270 
01271   CGAL_assertion(is_valid(a));
01272   CGAL_assertion(is_valid(b));
01273   CGAL_assertion((a.is_rational() || b.is_rational()) || (a.gamma() == b.gamma()));
01274 
01275   if(a.is_rational() && b.is_rational()) {
01276     return Root_of_2<RT>(a.alpha() * b.alpha());
01277   }
01278 
01279   if(a.is_rational()) {
01280     if(CGAL_NTS is_zero(a.alpha())) return Root_of_2<RT>();
01281     return Root_of_2<RT>(b.alpha() * a.alpha(), b.beta() * a.alpha(), b.gamma());
01282   }
01283 
01284   if(b.is_rational()) {
01285     if(CGAL_NTS is_zero(b.alpha())) return Root_of_2<RT>();
01286     return Root_of_2<RT>(a.alpha() * b.alpha(), a.beta() * b.alpha(), a.gamma());
01287   }
01288 
01289   return Root_of_2<RT>(b.beta() * a.beta() * a.gamma() + a.alpha() * b.alpha(),
01290                        a.alpha() * b.beta() + a.beta() * b.alpha(),
01291                        a.gamma());
01292 }
01293 
01294 template < typename RT > inline
01295 Root_of_2<RT> operator/(const Root_of_2<RT> &a, const Root_of_2<RT> &b)
01296 {
01297   return b.inverse() * a;
01298 }
01299 
01300 template < typename RT >
01301 double
01302 to_double(const Root_of_2<RT> &x)
01303 {
01304   if (x.is_rational()) {
01305     return (CGAL_NTS to_double(x.alpha()));
01306   }
01307   return CGAL_NTS to_double(x.alpha()) +
01308          CGAL_NTS to_double(x.beta()) *
01309          (std::sqrt)(CGAL_NTS to_double(x.gamma()));
01310 }
01311 
01312 template < typename RT >
01313 std::ostream &
01314 operator<<(std::ostream &os, const Root_of_2<RT> &r)
01315 {
01316   if(r.is_rational()) {
01317     return os << r.is_rational() << " " << r.alpha();
01318   } else {
01319     return os << r.is_rational() << " " << r.alpha() << " "
01320               << r.beta() << " "
01321               << r.gamma();
01322   }
01323 }
01324 
01325 template < typename RT >
01326 std::istream &
01327 operator>>(std::istream &is, Root_of_2<RT> &r)
01328 {
01329   typedef typename Root_of_traits< RT >::RootOf_1  FT;
01330   FT a,b,c;
01331   bool rat;
01332   is >> rat;
01333   if(rat) {
01334     is >> a;
01335     if(is) r = Root_of_2<RT>(a);
01336     return is;
01337   }
01338   is >> a >> b >> c;
01339   if(is) r = Root_of_2<RT>(a,b,c);
01340   return is;
01341 }
01342 
01343 
01344 template < typename RT >
01345 void
01346 print(std::ostream &os, const Root_of_2<RT> &r)
01347 {
01348   if(r.is_rational()) {
01349     os << "(" << r.alpha() << ")";
01350   } else {
01351     os << "(" << r.alpha() << " + " << r.beta() <<
01352           "*sqrt(" << r.gamma() << ")"<< ")";
01353   }
01354 }
01355 
01356 template < typename RT >
01357 class Is_valid<Root_of_2<RT> >: public std::unary_function<Root_of_2<RT> , bool>{
01358 public:
01359     bool operator()(const Root_of_2<RT> &r)
01360     {
01361         return r.is_valid();
01362     }
01363 };
01364 
01365 template <class NT>
01366 inline const Root_of_2<NT>& min BOOST_PREVENT_MACRO_SUBSTITUTION
01367 (const Root_of_2<NT>& p, const Root_of_2<NT>& q){
01368   return (std::min)(p, q);
01369 }
01370 template <class NT> 
01371 inline const Root_of_2<NT>& max BOOST_PREVENT_MACRO_SUBSTITUTION
01372 (const Root_of_2<NT>& p, const Root_of_2<NT>& q){
01373   return (std::max)(p, q);
01374 }
01375 
01376 } // namespace CGAL
01377 
01378 #undef CGAL_int
01379 #undef CGAL_double
01380 
01381 #endif // CGAL_ROOT_OF_2_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines