BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Polynomial/polynomial_gcd_implementations.h
Go to the documentation of this file.
00001 // Copyright (c) 2008 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/Polynomial/include/CGAL/Polynomial/polynomial_gcd_implementations.h $
00016 // $Id: polynomial_gcd_implementations.h 47254 2008-12-06 21:18:27Z afabri $
00017 //
00018 //
00019 // Author(s)     : Michael Hemmer   <hemmer@informatik.uni-mainz.de>  
00020 
00021 #ifndef CGAL_POLYNOMIAL_GCD_IMPLEMENTATIONS_H
00022 #define CGAL_POLYNOMIAL_GCD_IMPLEMENTATIONS_H
00023 
00024 
00025 #include <CGAL/basic.h>
00026 #include <CGAL/Polynomial.h>
00027 #include <CGAL/Real_timer.h>
00028 #include <CGAL/polynomial_utils.h>
00029 #include <CGAL/Polynomial/hgdelta_update.h>
00030 #include <CGAL/Polynomial/polynomial_gcd.h>
00031 
00032 
00033 namespace CGAL {  
00034 namespace CGALi {
00035 
00036 template <class NT>
00037 inline
00038 Polynomial<NT> gcd_utcf_UFD(
00039         Polynomial<NT> p1, Polynomial<NT> p2
00040 ) {
00041     typedef CGAL::Polynomial_traits_d<Polynomial<NT> > PT;
00042     // implemented using the subresultant algorithm for gcd computation
00043     // see [Cohen, 1993], algorithm 3.3.1
00044     // handle trivial cases
00045     if (p1.is_zero()){
00046         if (p2.is_zero()) return Polynomial<NT>(NT(1));
00047         else {
00048             return CGAL::canonicalize(p2);
00049         }
00050     }
00051     if (p2.is_zero()){
00052         return CGAL::canonicalize(p1);
00053     }
00054     if (p2.degree() > p1.degree()) {
00055         Polynomial<NT> p3 = p1; p1 = p2; p2 = p3;
00056     }
00057 
00058     // compute gcd of content
00059     NT p1c = p1.content(), p2c = p2.content();
00060     NT gcdcont = CGAL::gcd(p1c,p2c);
00061 
00062     // compute gcd of primitive parts
00063     p1 /= p1c; p2 /= p2c;
00064 
00065     NT dummy;
00066     Polynomial<NT> q, r;
00067 
00068     NT g = NT(1), h = NT(1);
00069     for (;;) { 
00070         Polynomial<NT>::pseudo_division(p1, p2, q, r, dummy);
00071         if (r.is_zero()) { break; }
00072         
00073         if (r.degree() == 0) { 
00074             return CGAL::canonicalize(Polynomial<NT>(gcdcont));
00075         }
00076         int delta = p1.degree() - p2.degree();
00077         p1 = p2;
00078         p2 = r / (g * ipower(h, delta));
00079         g = p1.lcoeff();
00080         // h = h^(1-delta) * g^delta
00081         CGAL::CGALi::hgdelta_update(h, g, delta);
00082     }
00083 
00084     p2 /= p2.content() * p2.unit_part();
00085 
00086     // combine both parts to proper gcd
00087     p2 *= gcdcont; 
00088 
00089     return CGAL::canonicalize(p2);
00090 }
00091 
00092 template <class NT>
00093 inline
00094 Polynomial<NT> gcd_Euclidean_ring(
00095         Polynomial<NT> p1, Polynomial<NT> p2
00096 ) {
00097 //    std::cout<<" gcd_Field"<<std::endl;
00098     // handle trivial cases
00099     if (p1.is_zero()){
00100         if (p2.is_zero()) return Polynomial<NT>(NT(1));
00101         else return p2 / p2.unit_part();
00102     }
00103     if (p2.is_zero())
00104         return p1 / p1.unit_part();
00105     if (p2.degree() > p1.degree()) {
00106         Polynomial<NT> p3 = p1; p1 = p2; p2 = p3;
00107     }
00108 
00109     Polynomial<NT> q, r;
00110     while (!p2.is_zero()) { 
00111         Polynomial<NT>::euclidean_division(p1, p2, q, r);
00112         p1 = p2; p2 = r;
00113     }
00114     p1 /= p1.lcoeff();
00115     p1.simplify_coefficients();
00116     return p1;
00117 }
00118 
00119 template <class NT>
00120 inline
00121 NT content_utcf_(const Polynomial<NT>& p)
00122 {
00123     typename Algebraic_structure_traits<NT>::Integral_division idiv;
00124     typename Algebraic_structure_traits<NT>::Unit_part upart;
00125     typedef typename Polynomial<NT>::const_iterator const_iterator;
00126 
00127     const_iterator it = p.begin(), ite = p.end();
00128     while (*it == NT(0)) it++;
00129     NT cont = idiv(*it, upart(*it));
00130     for( ; it != ite; it++) {
00131         if (cont == NT(1)) break;
00132         if (*it != NT(0)) cont = CGALi::gcd_utcf_(cont, *it);
00133     }
00134     
00135     return cont;
00136 }
00137 
00138 
00139 template <class NT>
00140 inline 
00141 Polynomial<NT> gcd_utcf_Integral_domain( Polynomial<NT> p1, Polynomial<NT> p2){
00142   // std::cout<<" gcd_utcf_Integral_domain"<<std::endl;
00143   typedef Polynomial<NT> POLY; 
00144   
00145   // handle trivial cases
00146     if (p1.is_zero()){
00147       if (p2.is_zero()){
00148             return Polynomial<NT>(NT(1));
00149         }else{
00150             return CGAL::canonicalize(p2);
00151         }
00152     }
00153     if (p2.is_zero()){
00154         return CGAL::canonicalize(p1);
00155     }
00156 
00157     if (p2.degree() > p1.degree()) {
00158         Polynomial<NT> p3 = p1; p1 = p2; p2 = p3;
00159     }
00160     
00161     // remove redundant scalar factors
00162     p1=CGAL::canonicalize(p1);
00163     p2=CGAL::canonicalize(p2); 
00164 
00165     // compute content of p1 and p2
00166     NT p1c = CGALi::content_utcf_(p1);
00167     NT p2c = CGALi::content_utcf_(p2);
00168     
00169    
00170     // compute gcd of content
00171     NT gcdcont = CGALi::gcd_utcf_(p1c, p2c);
00172 
00173     // compute gcd of primitive parts
00174     p1 = integral_division_up_to_constant_factor(p1, POLY(p1c)); 
00175     p2 = integral_division_up_to_constant_factor(p2, POLY(p2c)); 
00176 
00177  
00178     Polynomial<NT> q, r;
00179     
00180     // TODO measure preformance of both methodes with respect to 
00181     // univariat polynomials on Integeres
00182     // univariat polynomials on Sqrt_extension<Integer,Integer>
00183     // multivariat polynomials
00184     // May write specializations for different cases 
00185 #if 0
00186     // implemented using the subresultant algorithm for gcd computation
00187     // with respect to constant scalar factors
00188     // see [Cohen, 1993], algorithm 3.3.1
00189     NT g = NT(1), h = NT(1), dummy;
00190     for (;;) { 
00191         Polynomial<NT>::pseudo_division(p1, p2, q, r, dummy);
00192         if (r.is_zero()) { break; }
00193         if (r.degree() == 0) { return Polynomial<NT>(gcdcont); }
00194         int delta = p1.degree() - p2.degree();
00195         p1 = p2;
00196         p2 = r / (g * ipower(h, delta));
00197         g = p1.lcoeff();
00198         // h = h^(1-delta) * g^delta
00199         CGAL::CGALi::hgdelta_update(h, g, delta);
00200     }
00201 #else
00202     // implentaion using just the 'naive' methode
00203     // but performed much better as the one by Cohen
00204     // (for univariat polynomials with Sqrt_extension coeffs )
00205     NT dummy;
00206     for (;;) { 
00207         Polynomial<NT>::pseudo_division(p1, p2, q, r, dummy);    
00208         if (r.is_zero()) { break; }
00209         if (r.degree() == 0) { return Polynomial<NT>(gcdcont); }
00210         p1 = p2;
00211         p2 = r ;
00212         p2=CGAL::canonicalize(p2);   
00213     }
00214 #endif
00215 
00216     p2 = integral_division_up_to_constant_factor(p2, POLY(content_utcf_(p2)));
00217 
00218     // combine both parts to proper gcd
00219     p2 *= gcdcont;
00220 
00221     Polynomial<NT> result; 
00222     
00223     // make poly unique
00224     result = CGAL::canonicalize(p2);
00225     return result; 
00226 }
00227 
00228 
00229 }  // namespace CGALi
00230 
00231 }  // namespace CGAL
00232 
00233 #endif //CGAL_POLYNOMIAL_GCD_IMPLEMENTATIONS_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines