BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Algebraic_structure_traits.h
Go to the documentation of this file.
00001 // Copyright (c) 2006-2007 Max-Planck-Institute Saarbruecken (Germany).
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/Algebraic_foundations/include/CGAL/Algebraic_structure_traits.h $
00016 // $Id: Algebraic_structure_traits.h 45630 2008-09-18 13:53:47Z hemmer $
00017 //
00018 //
00019 // Author(s)     : Michael Hemmer    <hemmer@mpi-inf.mpg.de>
00020 //
00021 // =============================================================================
00022 
00023 
00024 #ifndef CGAL_ALGEBRAIC_STRUCTURE_TRAITS_H
00025 #define CGAL_ALGEBRAIC_STRUCTURE_TRAITS_H
00026 
00027 #include <CGAL/number_type_basic.h>
00028 #include <CGAL/type_traits.h>
00029 
00030 CGAL_BEGIN_NAMESPACE
00031 
00032 // REMARK: Some of the following comments and references are just copy & pasted
00033 //         from EXACUS and have to be adapted/removed in the future.
00034 
00035 // The tags for Algebra_type corresponding to the number type concepts
00036 // ===================================================================
00037 
00039 struct Integral_domain_without_division_tag {};
00040 
00042 struct Integral_domain_tag : public Integral_domain_without_division_tag {};
00043 
00045 struct Unique_factorization_domain_tag : public Integral_domain_tag {};
00046 
00048 struct Euclidean_ring_tag : public Unique_factorization_domain_tag {};
00049 
00051 struct Field_tag : public Integral_domain_tag {};
00052 
00054 struct Field_with_sqrt_tag : public Field_tag {};
00055 
00057 struct Field_with_kth_root_tag : public Field_with_sqrt_tag {};
00058 
00060 struct Field_with_root_of_tag : public Field_with_kth_root_tag {};
00061 
00062 
00063 // The algebraic structure traits template
00064 // =========================================================================
00065 template< class Type_ > 
00066 class Algebraic_structure_traits  {
00067   public:
00068     typedef Type_  Type;
00069     typedef Null_tag       Algebraic_category;
00070     typedef Null_tag       Is_exact;
00071     typedef Null_tag       Is_numerical_sensitive;
00072 
00073     typedef Null_functor Simplify;
00074     typedef Null_functor Unit_part;
00075     typedef Null_functor Integral_division;
00076     typedef Null_functor Is_square;    
00077     typedef Null_functor Gcd;
00078     typedef Null_functor Div_mod;
00079     typedef Null_functor Div;
00080     typedef Null_functor Mod;
00081     typedef Null_functor Square;
00082     typedef Null_functor Is_zero;
00083     typedef Null_functor Is_one;    
00084     typedef Null_functor Sqrt;
00085     typedef Null_functor Kth_root;
00086     typedef Null_functor Root_of; 
00087     typedef Null_functor Divides; 
00088 };
00089 
00090 // The algebraic structure traits base class
00091 // =========================================================================
00092 template< class Type, class Algebra_type >
00093 class Algebraic_structure_traits_base;
00094 
00098 template< class Type_ >
00099 class Algebraic_structure_traits_base< Type_, Null_tag > {
00100   public:
00101     typedef Type_  Type;
00102     typedef Null_tag       Algebraic_category;
00103     typedef Tag_false      Is_exact;
00104     typedef Null_tag       Is_numerical_sensitive;
00105     typedef Null_tag       Boolean; 
00106 
00107     // does nothing by default
00108     class Simplify 
00109       : public std::unary_function< Type&, void > {
00110       public:
00111         void operator()( Type& ) const {}
00112     };
00113 
00114     typedef Null_functor Unit_part;
00115     typedef Null_functor Integral_division;
00116     typedef Null_functor Is_square;    
00117     typedef Null_functor Gcd;
00118     typedef Null_functor Div_mod;
00119     typedef Null_functor Div;
00120     typedef Null_functor Mod;
00121     typedef Null_functor Square;
00122     typedef Null_functor Is_zero;
00123     typedef Null_functor Is_one;    
00124     typedef Null_functor Sqrt;
00125     typedef Null_functor Kth_root;
00126     typedef Null_functor Root_of; 
00127     typedef Null_functor Divides; 
00128 };
00129 
00135 template< class Type_ >
00136 class Algebraic_structure_traits_base< Type_, 
00137                                        Integral_domain_without_division_tag > 
00138     : public Algebraic_structure_traits_base< Type_, 
00139                                               Null_tag > {
00140   public:
00141     typedef Type_                                 Type;
00142     typedef Integral_domain_without_division_tag  Algebraic_category;
00143     typedef bool                                  Boolean;
00144 
00145     // returns Type(1) by default
00146     class Unit_part 
00147       : public std::unary_function< Type, Type > { 
00148       public:
00149         Type operator()( const Type& x ) const {
00150           return( x < Type(0)) ? 
00151                   Type(-1) : Type(1); 
00152         }
00153     };
00154     
00155     class Square 
00156       : public std::unary_function< Type, Type > {
00157       public:        
00158         Type operator()( const Type& x ) const {
00159           return x*x;
00160         }
00161     };
00162     
00163     class Is_zero 
00164       : public std::unary_function< Type, bool > {
00165       public:        
00166         bool operator()( const Type& x ) const {
00167           return x == Type(0);
00168         }
00169     };
00170 
00171     class Is_one 
00172       : public std::unary_function< Type, bool > {
00173       public:        
00174         bool operator()( const Type& x ) const {
00175           return x == Type(1);
00176         }
00177     };
00178 
00179 };
00180 
00181 
00188 template< class Type_ >
00189 class Algebraic_structure_traits_base< Type_, 
00190                                        Integral_domain_tag >
00191     : public Algebraic_structure_traits_base< Type_, 
00192                                        Integral_domain_without_division_tag > {
00193   public:
00194     typedef Type_       Type;
00195     typedef Integral_domain_tag  Algebraic_category;
00196 };
00197 
00198 
00205 template< class Type_ >
00206 class Algebraic_structure_traits_base< Type_, 
00207                                        Unique_factorization_domain_tag >
00208     : public Algebraic_structure_traits_base< Type_, 
00209                                               Integral_domain_tag > {
00210   public:
00211     typedef Type_  Type;
00212     typedef Unique_factorization_domain_tag    Algebraic_category;
00213 
00214   // Default implementation of Divides functor for unique factorization domains
00215   // x divides y if gcd(y,x) equals x up to inverses 
00216   class Divides 
00217     : public std::binary_function<Type,Type,bool>{ 
00218   public:
00219     bool operator()( const Type& x,  const Type& y) const {  
00220       typedef CGAL::Algebraic_structure_traits<Type> AST;
00221       typename AST::Gcd gcd;
00222       typename AST::Unit_part unit_part;
00223       typename AST::Integral_division idiv;
00224       return gcd(y,x) == idiv(x,unit_part(x));
00225     }
00226     // second operator computing q = x/y 
00227     bool operator()( const Type& x,  const Type& y, Type& q) const {    
00228       typedef CGAL::Algebraic_structure_traits<Type> AST;
00229       typename AST::Integral_division idiv;
00230       bool result = (*this)(x,y);
00231       if( result == true ) 
00232         q = idiv(x,y);
00233       return result; 
00234     }
00235     CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR_WITH_RT(Type,bool)
00236   };
00237 };
00238 
00239 
00242 template< class Type_ >
00243 class Algebraic_structure_traits_base< Type_, 
00244                                        Euclidean_ring_tag >
00245     : public Algebraic_structure_traits_base< Type_, 
00246                                               Unique_factorization_domain_tag > {
00247   public:
00248     typedef Type_        Type;
00249     typedef Euclidean_ring_tag    Algebraic_category;
00250 
00251     // maps to \c Div by default.
00252     class Integral_division 
00253       : public std::binary_function< Type, Type,
00254                                 Type > { 
00255       public:
00256         Type operator()( 
00257                 const Type& x, 
00258                 const Type& y) const { 
00259             typedef Algebraic_structure_traits<Type> AST; 
00260             typedef typename AST::Is_exact Is_exact;
00261             typename AST::Div actual_div;
00262             
00263             CGAL_precondition_msg( 
00264                     !Is_exact::value || actual_div( x, y) * y == x,
00265                     "'x' must be divisible by 'y' in "
00266                     "Algebraic_structure_traits<...>::Integral_div()(x,y)" );
00267             return actual_div( x, y);          
00268         }
00269         CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( Type )
00270     };
00271 
00272     // Algorithm from NiX/euclids_algorithm.h
00273     class Gcd 
00274       : public std::binary_function< Type, Type,
00275                                 Type > { 
00276       public:
00277         Type operator()( 
00278                 const Type& x, 
00279                 const Type& y) const {
00280             typedef Algebraic_structure_traits<Type> AST;
00281             typename AST::Mod mod;
00282             typename AST::Unit_part unit_part;
00283             typename AST::Integral_division integral_div;
00284             // First: the extreme cases and negative sign corrections.
00285             if (x == Type(0)) {
00286                 if (y == Type(0))  
00287                     return Type(0);
00288                 return integral_div( y, unit_part(y) );
00289             }
00290             if (y == Type(0))
00291                 return integral_div(x, unit_part(x) );
00292             Type u = integral_div( x, unit_part(x) );
00293             Type v = integral_div( y, unit_part(y) );
00294             // Second: assuming mod is the most expensive op here, 
00295             // we don't compute it unnecessarily if u < v
00296             if (u < v) {
00297                 v = mod(v,u);
00298                 // maintain invariant of v > 0 for the loop below
00299                 if ( v == Type(0) )
00300                     return u;
00301             }
00302             // Third: generic case of two positive integer values and u >= v.
00303             // The standard loop would be:
00304             //      while ( v != 0) {
00305             //          int tmp = mod(u,v);
00306             //          u = v;
00307             //          v = tmp;
00308             //      }
00309             //      return u;
00310             //
00311             // But we want to save us all the variable assignments and unroll
00312             // the loop. Before that, we transform it into a do {...} while()
00313             // loop to reduce branching statements.
00314             Type w;
00315             do {
00316                 w = mod(u,v);
00317                 if ( w == Type(0))
00318                     return v;
00319                 u = mod(v,w);
00320                 if ( u == Type(0))
00321                     return w;
00322                 v = mod(w,u);
00323             } while (v != Type(0));
00324             return u;
00325         }  
00326         CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( Type )
00327     };
00328 
00329     // based on \c Div and \c Mod.
00330     class Div_mod { 
00331     public:
00332         typedef Type    first_argument_type;
00333         typedef Type    second_argument_type;
00334         typedef Type&   third_argument_type;
00335         typedef Type&   fourth_argument_type;
00336         typedef void  result_type;
00337         void operator()( const Type& x, 
00338                 const Type& y, 
00339                 Type& q, Type& r) const {
00340             typedef Algebraic_structure_traits<Type> Traits;
00341             typename Traits::Div  actual_div;
00342             typename Traits::Mod  actual_mod;
00343             q = actual_div( x, y );
00344             r = actual_mod( x, y );          
00345             return;
00346         }
00347         
00348         template < class NT1, class NT2 >
00349         void operator()( 
00350                 const NT1& x, 
00351                 const NT2& y,
00352                 Type& q, 
00353                 Type& r ) const {
00354             typedef Coercion_traits< NT1, NT2 > CT;
00355             typedef typename CT::Type Type; 
00356             BOOST_STATIC_ASSERT(( 
00357               ::boost::is_same<Type , Type >::value));
00358             
00359             typename Coercion_traits< NT1, NT2 >::Cast cast;
00360             operator()( cast(x), cast(y), q, r );          
00361         }
00362     };
00363     
00364     // based on \c Div_mod.
00365     class Div 
00366       : public std::binary_function< Type, Type,
00367                                 Type > {
00368       public:
00369         Type operator()( const Type& x, 
00370                                         const Type& y) const {
00371           typename Algebraic_structure_traits<Type>
00372                                                     ::Div_mod actual_div_mod;
00373           Type q;     
00374           Type r;
00375           actual_div_mod( x, y, q, r );
00376           return q;
00377         };
00378         
00379         CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( Type )
00380     };
00381 
00382     // based on \c Div_mod.
00383     class Mod 
00384       : public std::binary_function< Type, Type,
00385                                 Type > { 
00386       public:
00387         Type operator()( const Type& x, 
00388                                         const Type& y) const {
00389           typename Algebraic_structure_traits<Type>
00390                                                     ::Div_mod actual_div_mod;
00391           Type q;     
00392           Type r;
00393           actual_div_mod( x, y, q, r );
00394           return r;
00395         };
00396         
00397         CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( Type )
00398     };
00399 
00400   // Divides for Euclidean Ring 
00401   class Divides 
00402     : public std::binary_function<Type, Type, bool>{
00403   public:
00404     bool operator()( const Type& x, const Type& y) const {
00405       typedef Algebraic_structure_traits<Type> AST;
00406       typename AST::Mod mod;
00407       CGAL_precondition(typename AST::Is_zero()(x) == false );
00408       return typename AST::Is_zero()(mod(y,x));
00409     }
00410     // second operator computing q 
00411     bool operator()( const Type& x, const Type& y, Type& q) const {
00412       typedef Algebraic_structure_traits<Type> AST;
00413       typename AST::Div_mod div_mod;
00414       CGAL_precondition(typename AST::Is_zero()(x) == false );
00415       Type r;
00416       div_mod(y,x,q,r);
00417       return (typename AST::Is_zero()(r));
00418     }
00419     CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR_WITH_RT(Type,bool)
00420   };
00421 };
00422 
00423 
00431 //
00432 template< class Type_ >
00433 class Algebraic_structure_traits_base< Type_, Field_tag >
00434     : public Algebraic_structure_traits_base< Type_, 
00435                                               Integral_domain_tag > {
00436   public:
00437     typedef Type_        Type;
00438     typedef Field_tag             Algebraic_category;
00439 
00440     // returns the argument \a a by default
00441     class Unit_part 
00442       : public std::unary_function< Type, Type > { 
00443       public:
00444         Type operator()( const Type& x ) const {
00445             return( x == Type(0)) ? Type(1) : x;
00446         }
00447     };
00448     // maps to \c operator/ by default.
00449     class Integral_division 
00450       : public std::binary_function< Type, Type,
00451                                 Type > { 
00452       public:
00453         Type operator()( const Type& x, 
00454                                         const Type& y) const { 
00455             typedef Algebraic_structure_traits<Type> AST; 
00456             typedef typename AST::Is_exact Is_exact;
00457             CGAL_precondition_code( bool ie = Is_exact::value; )
00458             CGAL_precondition_msg( !ie || (x / y) * y  == x,
00459                     "'x' must be divisible by 'y' in "
00460                     "Algebraic_structure_traits<...>::Integral_div()(x,y)" );
00461             return x / y;
00462         }
00463       CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( Type )
00464     };
00465 
00466   // Default implementation of Divides functor for Field: 
00467   // returns always true
00468   // \pre: x != 0
00469   class Divides
00470     : public std::binary_function< Type, Type, bool > { 
00471   public:
00472     bool operator()( const Type& CGAL_precondition_code(x), const Type& /* y */) const {
00473       typedef Algebraic_structure_traits<Type> AST;
00474       CGAL_precondition( typename AST::Is_zero()(x) == false );
00475       return true;
00476     } 
00477     // second operator computing q
00478     bool operator()( const Type& x, const Type& y, Type& q) const {
00479       typedef Algebraic_structure_traits<Type> AST;
00480       CGAL_precondition( typename AST::Is_zero()(x) == false );
00481       q = y/x;
00482       return true;
00483     }
00484     CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR_WITH_RT(Type,bool)
00485   };
00486 };
00487 
00488 
00495 //
00496 template< class Type_ >
00497 class Algebraic_structure_traits_base< Type_, 
00498                                        Field_with_sqrt_tag>
00499     : public Algebraic_structure_traits_base< Type_, 
00500                                               Field_tag> {
00501   public:
00502     typedef Type_        Type;
00503     typedef Field_with_sqrt_tag   Algebraic_category;
00504 
00505     struct Is_square
00506         :public std::binary_function<Type,Type&,bool>
00507     {
00508         bool operator()(const Type& ) const {return true;}
00509         bool operator()(
00510                 const Type& x,
00511                 Type      & result) const {
00512             typename Algebraic_structure_traits<Type>::Sqrt sqrt;
00513             result = sqrt(x);
00514             return true;
00515         }
00516     };
00517 };
00518 
00525 //
00526 template< class Type_ >
00527 class Algebraic_structure_traits_base< Type_, 
00528                                        Field_with_kth_root_tag>
00529     : public Algebraic_structure_traits_base< Type_, 
00530                                               Field_with_sqrt_tag> {
00531     
00532     
00533     
00534   public:
00535     typedef Type_        Type;
00536     typedef Field_with_kth_root_tag   Algebraic_category;
00537 };
00538 
00539 
00540 
00541 
00548 //
00549 template< class Type_ >
00550 class Algebraic_structure_traits_base< Type_, 
00551                                        Field_with_root_of_tag >
00552     : public Algebraic_structure_traits_base< Type_, 
00553                                               Field_with_kth_root_tag > {
00554   public:
00555     typedef Type_           Type;
00556     typedef Field_with_root_of_tag   Algebraic_category;
00557 };
00558 
00559 // Some common functors to be used by AST specializations
00560 namespace INTERN_AST {
00561   template< class Type >
00562   class Div_per_operator 
00563     : public std::binary_function< Type, Type, 
00564                               Type > {
00565     public:      
00566       Type operator()( const Type& x, 
00567                                       const Type& y ) const {
00568         return x / y;
00569       }
00570       
00571       CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( Type )
00572   };
00573   
00574   template< class Type >
00575   class Mod_per_operator 
00576     : public std::binary_function< Type, Type,
00577                               Type > {
00578     public:
00579       Type operator()( const Type& x, 
00580                                       const Type& y ) const {
00581         return x % y;
00582       }
00583       
00584       CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( Type )
00585   };
00586   
00587   template< class Type >
00588   class Is_square_per_sqrt
00589     : public std::binary_function< Type, Type&,
00590                               bool > {
00591     public:      
00592       bool operator()( const Type& x, 
00593                        Type& y ) const {
00594           typename Algebraic_structure_traits< Type >::Sqrt
00595               actual_sqrt;
00596           y = actual_sqrt( x );
00597           return y * y == x;
00598       }
00599       bool operator()( const Type& x) const {
00600           Type dummy;
00601           return operator()(x,dummy);
00602       }
00603   };
00604 } // INTERN_AST
00605 CGAL_END_NAMESPACE
00606 
00607 #endif  // CGAL_ALGEBRAIC_STRUCTURE_TRAITS_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines