BWAPI
|
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