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