BWAPI
|
00001 // Copyright (c) 1997 INRIA Sophia-Antipolis (France). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://afabri@scm.gforge.inria.fr/svn/cgal/trunk/Alpha_shapes_2/include/CGAL/Alpha_shape_2.h $ 00015 // $Id: Alpha_shape_2.h 47026 2008-11-25 13:21:09Z afabri $ 00016 // 00017 // 00018 // Author(s) : Michael Hemmer 00019 // 00020 // ============================================================================ 00021 #ifndef CGAL_POLYNOMIAL_SQUARE_FREE_FACTORIZATION_H 00022 #define CGAL_POLYNOMIAL_SQUARE_FREE_FACTORIZATION_H 00023 00024 #include <CGAL/basic.h> 00025 #include <CGAL/Polynomial/fwd.h> 00026 #include <CGAL/Polynomial/misc.h> 00027 #include <CGAL/Polynomial/Polynomial.h> 00028 00029 CGAL_BEGIN_NAMESPACE 00030 namespace CGALi { 00031 00032 // square-free factorization 00033 // 00034 // the implementation uses two dispatches: 00035 // a) first look at the coefficient's algebra type 00036 // b) if the algebra type is of the concept field, try to decompose 00037 // the same holds for square-free factorization up to constant factors (utcf) 00038 // 00039 // sqff -------> algebra type ? ----field-----> decomposable ? 00040 // | A | | 00041 // UFD | no yes 00042 // | | | | 00043 // V | | 00044 // Yun's algo <---------------------- | 00045 // A | 00046 // | | | 00047 // UFD | V 00048 // | | decompose and use 00049 // sqff_utcf --> algebra_type ? ----field-- sqff_utcf with numerator 00050 // | 00051 // integral domain 00052 // | 00053 // V 00054 // Yun's algo (utcf) 00055 00056 template <class IC, class OutputIterator1, class OutputIterator2> 00057 inline int square_free_factorize(const IC&, OutputIterator1, OutputIterator2){ 00058 return 0; 00059 } 00060 template <class IC, class OutputIterator1, class OutputIterator2> 00061 inline int square_free_factorize_for_regular_polynomial(const IC&, OutputIterator1, OutputIterator2){ 00062 return 0; 00063 } 00064 00065 template <class Coeff, class OutputIterator1, class OutputIterator2> 00066 inline int square_free_factorize(const Polynomial<Coeff>&, OutputIterator1, OutputIterator2); 00067 template <class Coeff, class OutputIterator1, class OutputIterator2> 00068 inline int square_free_factorize_for_regular_polynomial(const Polynomial<Coeff>&, OutputIterator1, OutputIterator2); 00069 template <class Coeff, class OutputIterator1, class OutputIterator2> 00070 inline int square_free_factorize_for_regular_polynomial_(const Polynomial<Coeff>&, OutputIterator1, OutputIterator2, CGAL::Tag_true); 00071 template <class Coeff, class OutputIterator1, class OutputIterator2> 00072 inline int square_free_factorize_for_regular_polynomial_(const Polynomial<Coeff>&, OutputIterator1, OutputIterator2, CGAL::Tag_false); 00073 template <class Coeff, class OutputIterator1, class OutputIterator2> 00074 inline int square_free_factorize_for_regular_polynomial_(const Polynomial<Coeff>&, OutputIterator1, OutputIterator2, Integral_domain_tag); 00075 template <class Coeff, class OutputIterator1, class OutputIterator2> 00076 inline int square_free_factorize_for_regular_polynomial_(const Polynomial<Coeff>&, OutputIterator1, OutputIterator2, Unique_factorization_domain_tag); 00077 00078 00079 00080 00081 template <class Coeff, class OutputIterator1, class OutputIterator2> 00082 inline int square_free_factorize 00083 (const Polynomial<Coeff>& poly, OutputIterator1 factors, OutputIterator2 multiplicities) 00084 { 00085 typedef Polynomial<Coeff> POLY; 00086 typedef Polynomial_traits_d< POLY > PT; 00087 typedef typename PT::Univariate_content_up_to_constant_factor Ucont_utcf; 00088 typedef typename PT::Integral_division_up_to_constant_factor Idiv_utcf; 00089 00090 if (typename PT::Total_degree()(poly) == 0){return 0;} 00091 00092 Coeff ucont_utcf = Ucont_utcf()(poly); 00093 POLY regular_poly = Idiv_utcf()(poly,ucont_utcf); 00094 00095 int result = square_free_factorize_for_regular_polynomial( 00096 regular_poly, factors, multiplicities); 00097 00098 if (typename PT::Total_degree()(ucont_utcf) > 0){ 00099 typedef std::vector< Coeff > Factors_uc; 00100 typedef std::vector< int > Multiplicities_uc; 00101 Factors_uc factors_uc; 00102 Multiplicities_uc multiplicities_uc; 00103 result += square_free_factorize( ucont_utcf, 00104 std::back_inserter(factors_uc), 00105 std::back_inserter(multiplicities_uc) ); 00106 00107 for( typename Factors_uc::iterator it = factors_uc.begin(); 00108 it != factors_uc.end(); ++it ){ 00109 *factors++ = POLY(*it); 00110 } 00111 for( Multiplicities_uc::iterator it = multiplicities_uc.begin(); 00112 it != multiplicities_uc.end(); ++it ){ 00113 *multiplicities++ = (*it); 00114 } 00115 } 00116 return result; 00117 } 00118 00119 template <class Coeff, class OutputIterator1, class OutputIterator2> 00120 inline int square_free_factorize_for_regular_polynomial 00121 (const Polynomial<Coeff>& p, OutputIterator1 factors, OutputIterator2 multiplicities){ 00122 typedef Polynomial<Coeff> POLY; 00123 typedef typename CGAL::Fraction_traits<POLY>::Is_fraction Is_fraction; 00124 return square_free_factorize_for_regular_polynomial_(p,factors,multiplicities,Is_fraction()); 00125 } 00126 00127 template <class Coeff, class OutputIterator1, class OutputIterator2> 00128 inline int square_free_factorize_for_regular_polynomial_ 00129 (const Polynomial<Coeff>& p, OutputIterator1 factors, OutputIterator2 multiplicities, CGAL::Tag_true){ 00130 00131 typedef Polynomial<Coeff> POLY; 00132 typedef Polynomial_traits_d< POLY > PT; 00133 typedef Fraction_traits<POLY> FT; 00134 00135 typename FT::Numerator_type num; 00136 typename FT::Denominator_type denom; 00137 typename FT::Decompose()(p,num,denom); 00138 00139 std::vector<typename FT::Numerator_type> ifacs; 00140 int result = square_free_factorize_for_regular_polynomial(num,std::back_inserter(ifacs),multiplicities); 00141 00142 typedef typename std::vector<typename FT::Numerator_type>::iterator Iterator; 00143 denom = typename FT::Denominator_type(1); 00144 for ( Iterator it = ifacs.begin(); it != ifacs.end(); ++it) { 00145 POLY q = typename FT::Compose()(*it, denom); 00146 *factors++ = typename PT::Canonicalize()(q); 00147 } 00148 00149 return result; 00150 } 00151 00152 template <class Coeff, class OutputIterator1, class OutputIterator2> 00153 inline int square_free_factorize_for_regular_polynomial_ 00154 (const Polynomial<Coeff>& p, OutputIterator1 factors, OutputIterator2 multiplicities, CGAL::Tag_false){ 00155 typedef Polynomial<Coeff> POLY; 00156 typedef typename Algebraic_structure_traits<POLY>::Algebraic_category Algebraic_category; 00157 return square_free_factorize_for_regular_polynomial_(p,factors,multiplicities,Algebraic_category()); 00158 } 00159 00160 template <class Coeff, class OutputIterator1, class OutputIterator2> 00161 inline int square_free_factorize_for_regular_polynomial_ 00162 (const Polynomial<Coeff>& p, OutputIterator1 factors, OutputIterator2 multiplicities, Integral_domain_tag){ 00163 // Yun's Square-Free Factorization 00164 // see [Geddes et al, 1992], Algorithm 8.2 00165 00166 typedef Polynomial<Coeff> POLY; 00167 typedef Polynomial_traits_d<POLY> PT; 00168 typedef typename PT::Innermost_coefficient_type IC; 00169 typename PT::Innermost_leading_coefficient ilcoeff; 00170 //typename PT::Innermost_coefficient_to_polynomial ictp; 00171 typename PT::Construct_innermost_coefficient_const_iterator_range range; 00172 typename Algebraic_extension_traits<IC>::Denominator_for_algebraic_integers dfai; 00173 typename Algebraic_extension_traits<IC>::Normalization_factor nfac; 00174 typename Scalar_factor_traits<POLY>::Scalar_factor sfac; 00175 typename Scalar_factor_traits<POLY>::Scalar_div sdiv; 00176 typedef typename Scalar_factor_traits<POLY>::Scalar Scalar; 00177 00178 00179 if (typename PT::Total_degree()(p) == 0) return 0; 00180 00181 POLY a = CGAL::canonicalize(p); 00182 POLY b = diff(a); 00183 POLY c = CGAL::CGALi::gcd_utcf(a, b); 00184 00185 if (c == Coeff(1)) { 00186 *factors = a; 00187 *multiplicities = 1; 00188 return 1; 00189 } 00190 00191 int i = 1, n = 0; 00192 00193 // extending both polynomials a and b by the denominator for algebraic 00194 // integers, which comes out from c=gcd(a,b), such that a and b are 00195 // divisible by c 00196 IC lcoeff = ilcoeff(c); 00197 IC denom = dfai(range(c).first, range(c).second); 00198 lcoeff *= denom * nfac(denom); 00199 POLY w = (a * POLY(lcoeff)) / c; 00200 POLY y = (b * POLY(lcoeff)) / c; 00201 00202 // extracting a common scalar factor out of w=a/c and y=b/c simultaneously, 00203 // such that the parts in z=y-w' are canceled out as they should 00204 Scalar sfactor = sfac(y,sfac(w)); 00205 sdiv(w, sfactor); 00206 sdiv(y, sfactor); 00207 00208 POLY z = y - diff(w); 00209 POLY g; 00210 00211 while (!z.is_zero()) { 00212 g = CGAL::CGALi::gcd_utcf(w, z); 00213 if (g.degree() > 0) { 00214 *factors++ = g; 00215 *multiplicities++ = i; 00216 n++; 00217 } 00218 i++; 00219 lcoeff = ilcoeff(g); // same as above 00220 denom =dfai(range(c).first, range(c).second); 00221 lcoeff *= denom * nfac(denom); 00222 w = (w * POLY(lcoeff)) / g; 00223 y = (z * POLY(lcoeff)) / g; 00224 Scalar sfactor = sfac(y,sfac(w)); 00225 sdiv(w, sfactor); 00226 sdiv(y, sfactor); 00227 00228 z = y - diff(w); 00229 } 00230 00231 *factors = w; 00232 *multiplicities++ = i; 00233 n++; 00234 00235 return n; 00236 } 00237 00238 template <class Coeff, class OutputIterator1, class OutputIterator2> 00239 inline int square_free_factorize_for_regular_polynomial_ 00240 (const Polynomial<Coeff>& p, OutputIterator1 factors, OutputIterator2 multiplicities, Unique_factorization_domain_tag){ 00241 // Yun's Square-Free Factorization 00242 // see [Geddes et al, 1992], Algorithm 8.2 00243 /* 00244 @inproceedings{y-osfda-76, 00245 author = {David Y.Y. Yun}, 00246 title = {On square-free decomposition algorithms}, 00247 booktitle = {SYMSAC '76: Proceedings of the third ACM symposium on Symbolic 00248 and algebraic computation}, 00249 year = {1976}, 00250 pages = {26--35}, 00251 location = {Yorktown Heights, New York, United States}, 00252 doi = {http://doi.acm.org/10.1145/800205.806320}, 00253 publisher = {ACM Press}, 00254 address = {New York, NY, USA}, 00255 } 00256 */ 00257 00258 typedef Polynomial<Coeff> POLY; 00259 typedef Polynomial_traits_d<POLY> PT; 00260 00261 if (typename PT::Total_degree()(p) == 0) return 0; 00262 POLY a = CGAL::canonicalize(p); 00263 00264 POLY b = diff(a); 00265 POLY c = CGAL::gcd(a, b); 00266 00267 if (c == Coeff(1)) { 00268 *factors = a; 00269 *multiplicities = 1; 00270 return 1; 00271 } 00272 00273 int i = 1, n = 0; 00274 POLY w = a/c, y = b/c, z = y - diff(w), g; 00275 while (!z.is_zero()) { 00276 g = CGAL::gcd(w, z); 00277 if (g.degree() > 0) { 00278 *factors++ = g; 00279 *multiplicities++ = i; 00280 n++; 00281 } 00282 i++; 00283 w /= g; 00284 y = z/g; 00285 z = y - diff(w); 00286 } 00287 *factors = w; 00288 *multiplicities++ = i; 00289 n++; 00290 00291 return n; 00292 } 00293 00294 00295 00296 00297 // square-free factorization utcf 00298 00299 template <class Coeff, class OutputIterator1, class OutputIterator2> 00300 inline int square_free_factorize_utcf 00301 (const Polynomial<Coeff>& p, OutputIterator1 factors, OutputIterator2 multiplicities) 00302 { 00303 return square_free_factorize(p,factors,multiplicities); 00304 } 00305 00306 template <class Coeff, class OutputIterator1, class OutputIterator2> 00307 inline int square_free_factorize_utcf_for_regular_polynomial 00308 (const Polynomial<Coeff>& p, OutputIterator1 factors, OutputIterator2 multiplicities) 00309 { 00310 return square_free_factorize_for_regular_polynomial(p,factors,multiplicities); 00311 } 00312 00313 00314 00315 00316 // filtered square-free factorization 00317 00318 // ### filtered versions #### 00319 00325 template <class Coeff, class OutputIterator1, class OutputIterator2> 00326 inline 00327 int filtered_square_free_factorize( 00328 Polynomial<Coeff> p, 00329 OutputIterator1 factors, 00330 OutputIterator2 multiplicities) 00331 { 00332 if(CGAL::CGALi::may_have_multiple_factor(p)){ 00333 return CGALi::square_free_factorize(p, factors, multiplicities); 00334 }else{ 00335 *factors++ = CGAL::canonicalize(p); 00336 *multiplicities++ = 1; 00337 return 1; 00338 } 00339 } 00340 00346 template <class Coeff, class OutputIterator1, class OutputIterator2> 00347 inline 00348 int filtered_square_free_factorize_utcf( const Polynomial<Coeff>& p, 00349 OutputIterator1 factors, 00350 OutputIterator2 multiplicities) 00351 { 00352 return filtered_square_free_factorize(p,factors,multiplicities); 00353 } 00354 00355 } // namespace CGALi 00356 CGAL_END_NAMESPACE 00357 00358 #endif // CGAL_POLYNOMIAL_SQUARE_FREE_FACTORIZATION_H