BWAPI
|
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/Chinese_remainder_traits.h $ 00016 // $Id: Chinese_remainder_traits.h 43073 2008-04-29 14:14:49Z hemmer $ 00017 // 00018 // 00019 // Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de> 00020 // 00021 // ============================================================================= 00022 00023 00024 #ifndef CGAL_CHINESE_REMAINDER_TRAITS_H 00025 #define CGAL_CHINESE_REMAINDER_TRAITS_H 1 00026 00027 #include <CGAL/basic.h> 00028 00029 #include <vector> 00030 00031 #include <CGAL/extended_euclidean_algorithm.h> 00032 00033 namespace CGAL{ 00034 namespace CGALi{ 00035 00036 template <class T_, class TAG> 00037 class Chinese_remainder_traits_base{ 00038 public: 00039 typedef T_ Type; 00040 typedef ::CGAL::Null_tag Scalar_type; 00041 typedef ::CGAL::Null_functor Chinese_remainder; 00042 }; 00043 } 00044 00045 template <class T> class Chinese_remainder_traits 00046 :public CGALi::Chinese_remainder_traits_base<T, 00047 typename Algebraic_structure_traits<T>::Algebraic_category>{}; 00048 00049 00050 namespace CGALi { 00051 template <class NT> 00052 class Chinese_remainder_traits_base<NT,Euclidean_ring_tag>{ 00053 public: 00054 typedef NT Type; 00055 typedef NT Scalar_type; 00056 00057 struct Chinese_remainder{ 00058 void operator() ( 00059 const Scalar_type& m1, const Scalar_type& m2, const Scalar_type& m, 00060 const Scalar_type& s, const Scalar_type& t, 00061 NT u1, NT u2, 00062 NT& u) const { 00063 #ifndef NDEBUG 00064 NT tmp,s_,t_; 00065 tmp = CGAL::extended_euclidean_algorithm(m1,m2,s_,t_); 00066 CGAL_precondition(tmp == NT(1)); 00067 CGAL_precondition(s_ == s); 00068 CGAL_precondition(t_ == t); 00069 #endif 00070 00071 typedef Algebraic_structure_traits<NT> AST; 00072 typename AST::Mod mod; 00073 //typename AST::Unit_part unit_part; 00074 typename AST::Integral_division idiv; 00075 00076 if(u1 < NT(0) ) u1 += m1; 00077 if(u2 < NT(0) ) u2 += m2; 00078 00079 CGAL_precondition(0 < m1); 00080 CGAL_precondition(u1 < m1); 00081 CGAL_precondition(u1 >= NT(0)); 00082 00083 CGAL_precondition(0 < m2); 00084 CGAL_precondition(u2 < m2); 00085 CGAL_precondition(u2 >= NT(0)); 00086 00087 NT v = mod(s*(u2-u1),m2); 00088 u = m1*v + u1; 00089 00090 // u is not unique yet! 00091 NT m_half = idiv(m-mod(m,NT(2)),NT(2)); 00092 if (u > m_half) u -= m ; 00093 if (u <= -m_half) u += m ; 00094 } 00095 00096 void operator() ( 00097 const Scalar_type& m1, const Type& u1, 00098 const Scalar_type& m2, const Type& u2, 00099 Scalar_type& m, Type& u) const { 00100 Scalar_type s,t; 00101 00102 CGAL::extended_euclidean_algorithm(m1,m2,s,t); 00103 m = m1 * m2; 00104 this->operator()(m1,m2,m,s,t,u1,u2,u); 00105 } 00106 }; 00107 }; 00108 00109 } // namespace CGALi 00110 } // namespace CGAL 00111 00112 #endif // CGAL_CHINESE_REMAINDER_TRAITS_H // 00113