BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Root_of_traits.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_traits.h $
00016 // $Id: Root_of_traits.h 44898 2008-08-12 08:35:42Z spion $
00017 //
00018 //
00019 // Author(s)     : Sylvain Pion, Monique Teillaud, Athanasios Kakargias, Michael Hemmer
00020 
00021 #ifndef CGAL_ROOT_OF_TRAITS_H
00022 #define CGAL_ROOT_OF_TRAITS_H
00023 
00024 #include <CGAL/number_type_basic.h>
00025 #include <CGAL/Root_of_2.h>
00026 #include <CGAL/Quotient.h>
00027 
00028 CGAL_BEGIN_NAMESPACE
00029 
00030 namespace CGALi {
00031 
00032 template < typename NT, class Algebraic_category>
00033 struct Root_of_traits_helper{
00034     typedef Quotient<NT> Root_of_1;
00035     typedef CGAL::Root_of_2<NT> Root_of_2;
00036     struct Make_root_of_2{
00037         typedef Root_of_2 result_type;
00038         Root_of_2 operator()(const NT& a, const NT& b, const NT& c){
00039             return Root_of_2(a,b,c);
00040         }
00041         Root_of_2 operator()(const NT& a, const NT& b, const NT& c, bool s){
00042             return Root_of_2(a,b,c,s);
00043         }
00044         Root_of_2 operator()(const Root_of_1& a,
00045                              const Root_of_1& b,
00046                              const Root_of_1& c){
00047             return Root_of_2(a,b,c);
00048         }
00049         Root_of_2 operator()(const Root_of_1& a,
00050                              const Root_of_1& b,
00051                              const Root_of_1& c,
00052                              bool s){
00053             return Root_of_2(a,b,c,s);
00054         }
00055     };
00056 };
00057 
00058 template < typename FT>
00059 struct Root_of_traits_helper < FT, Field_tag >
00060 {
00061     typedef FT               Root_of_1;
00062 private:
00063     typedef Fraction_traits<FT> FrT;
00064     // Field must be a Type (Decomposable)
00065     BOOST_STATIC_ASSERT((FrT::Is_fraction::value));
00066 
00067     typedef typename FrT::Numerator_type      RT;
00068     typedef typename FrT::Decompose Decompose;
00069 public:
00070     typedef CGAL::Root_of_2< RT >  Root_of_2;
00071 
00072     struct Make_root_of_2{
00073         typedef Root_of_2 result_type;
00074         Root_of_2
00075         operator()(const FT& a, const FT& b, const FT& c){
00076             return Root_of_2(a,b,c);
00077         }
00078         Root_of_2
00079         operator()(const FT& a, const FT& b, const FT& c, bool smaller){
00080             Decompose decompose;
00081             RT a_num,b_num,c_num;
00082             RT a_den,b_den,c_den; // Denomiantor same as RT
00083 
00084             decompose(a,a_num,a_den);
00085             decompose(b,b_num,b_den);
00086             decompose(c,c_num,c_den);
00087 
00088             RT a_ = a_num * b_den * c_den;
00089             RT b_ = b_num * a_den * c_den;
00090             RT c_ = c_num * a_den * b_den;
00091 
00092             return make_root_of_2(a_,b_,c_,smaller);
00093         }
00094     };
00095 };
00096 
00097 template < typename NT >
00098 struct Root_of_traits_helper < NT, Field_with_sqrt_tag >
00099 {
00100     typedef NT  Root_of_1;
00101     typedef NT  Root_of_2;
00102 
00103     struct Make_root_of_2{
00104         typedef NT result_type;
00105         // just a copy, not sure about the semantic of smaller
00106         NT operator()(const NT& a, const NT& b, const NT& c, bool smaller){
00107             // former make_root_of_2_sqrt()
00108             CGAL_assertion( a != 0 );
00109             NT discriminant = CGAL_NTS square(b) - a*c*4;
00110             CGAL_assertion( discriminant >= 0 );
00111             NT d = CGAL_NTS sqrt(discriminant);
00112             if ((smaller && a>0) || (!smaller && a<0))
00113                 d = -d;
00114             return (d-b)/(a*2);
00115         }
00116         // it's so easy
00117         NT operator()(const NT& a, const NT& b, const NT& c){
00118             return a + b * CGAL_NTS sqrt(c) ;
00119         }
00120     };
00121 };
00122 
00123 template < typename NT >
00124 struct Root_of_traits_helper < NT, Field_with_kth_root_tag >
00125     :public Root_of_traits_helper < NT, Field_with_sqrt_tag>{};
00126 
00127 template < typename NT >
00128 struct Root_of_traits_helper < NT, Field_with_root_of_tag >
00129     :public Root_of_traits_helper < NT, Field_with_sqrt_tag>{};
00130 
00131 
00132 } // namespace CGALi
00133 
00134 
00135 
00136 // Default Traits class for NT types
00137 template < typename NT >
00138 struct Root_of_traits
00139     : public CGALi::Root_of_traits_helper<NT,
00140       typename Algebraic_structure_traits<NT>::Algebraic_category> {
00141     typedef CGALi::Root_of_traits_helper<NT,
00142       typename Algebraic_structure_traits<NT>::Algebraic_category> Base;
00143     typedef typename Base::Root_of_1 RootOf_1;
00144     typedef typename Base::Root_of_2 RootOf_2;
00145 };
00146 
00147 template <bool B>
00148 struct Root_of_traits<Interval_nt<B> >{
00149   typedef Interval_nt<B> Root_of_1;
00150   typedef Interval_nt<B> Root_of_2;
00151   typedef Root_of_1 RootOf_1;
00152   typedef Root_of_2 RootOf_2;
00153   struct Make_root_of_2{
00154     typedef Interval_nt<B> result_type;
00155     // just a copy, not sure about the semantic of smaller
00156     Interval_nt<B> operator()(const Interval_nt<B>& a, const Interval_nt<B>& b, const Interval_nt<B>& c, bool smaller){
00157         // former make_root_of_2_sqrt()
00158         if (CGAL::possibly(a==0))
00159           return Interval_nt<B>::largest();
00160         Interval_nt<B> discriminant = CGAL_NTS square(b) - a*c*4;
00161         CGAL_assertion(discriminant >= 0);
00162         Interval_nt<B> d = CGAL_NTS sqrt(discriminant);
00163         if ((smaller && a>0) || (!smaller && a<0))
00164             d = -d;
00165         return (d-b)/(a*2);
00166     }
00167     // it's so easy
00168     Interval_nt<B> operator()(const Interval_nt<B>& a, const Interval_nt<B>& b, const Interval_nt<B>& c){
00169         return a + b * CGAL_NTS sqrt(c) ;
00170     }
00171   };
00172 };
00173 
00174 template < class NT >
00175 inline
00176 typename Root_of_traits< NT >::Root_of_2
00177 make_root_of_2(const NT &a, const NT &b, const NT &c)
00178 {
00179     typename Root_of_traits<NT>::Make_root_of_2 make_root_of_2;
00180     return make_root_of_2(a,b,c);
00181 }
00182 
00183 
00184 template < class NT >
00185 inline
00186 typename Root_of_traits< NT >::Root_of_2
00187 make_root_of_2(const NT &a, const NT &b, const NT &c,const bool smaller)
00188 {
00189     typename Root_of_traits<NT>::Make_root_of_2 make_root_of_2;
00190     return make_root_of_2(a,b,c,smaller);
00191 }
00192 
00193 CGAL_END_NAMESPACE
00194 
00195 #endif // CGAL_ROOT_OF_TRAITS_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines