// Copyright (c) 2000 Max-Planck-Institute Saarbruecken (Germany). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 3 of the License, // or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0+ // // // Author(s) : Michael Seel // Andreas Fabri namespace CGAL{ namespace Nef { inline void Polynomial::euclidean_div( const Polynomial& f, const Polynomial& g, Polynomial& q, Polynomial& r) { r = f; r.copy_on_write(); int rd=r.degree(), gd=g.degree(), qd; if ( rd < gd ) { q = Polynomial(int(0)); } else { qd = rd-gd+1; q = Polynomial(std::size_t(qd)); } while ( rd >= gd && !(r.is_zero())) { int S = r[rd] / g[gd]; qd = rd-gd; q.coeff(qd) += S; r.minus_offsetmult(g,S,qd); rd = r.degree(); } CGAL_postcondition( f==q*g+r ); } inline void Polynomial::pseudo_div( const Polynomial& f, const Polynomial& g, Polynomial& q, Polynomial& r, int& D) { CGAL_NEF_TRACEN("pseudo_div "<(0); r = f; D = 1; CGAL_postcondition(Polynomial(D)*f==q*g+r); return; } // now we know fd >= gd and f>=g int qd=fd-gd, delta=qd+1, rd=fd; { q = Polynomial( std::size_t(delta) ); }; // workaround for SUNPRO int G = g[gd]; // highest order coeff of g D = G; while (--delta) D*=G; // D = G^delta Polynomial res = Polynomial(D)*f; CGAL_NEF_TRACEN(" pseudo_div start "<= 0) { int F = res[rd]; // highest order coeff of res int t = F/G; // ensured to be integer by multiplication of D q.coeff(qd) = t; // store q coeff res.minus_offsetmult(g,t,qd); if (res.is_zero()) break; rd = res.degree(); qd = rd - gd; } r = res; CGAL_postcondition(Polynomial(D)*f==q*g+r); CGAL_NEF_TRACEN(" returning "< Polynomial::gcd( const Polynomial& p1, const Polynomial& p2) { CGAL_NEF_TRACEN("gcd("<(int(1)); else return p2.abs(); } if ( p2.is_zero() ) return p1.abs(); Polynomial f1 = p1.abs(); Polynomial f2 = p2.abs(); int f1c = f1.content(), f2c = f2.content(); f1 /= f1c; f2 /= f2c; int F = CGAL::gcd(f1c,f2c); Polynomial q,r; int M=1,D; bool first = true; while ( ! f2.is_zero() ) { Polynomial::pseudo_div(f1,f2,q,r,D); if (!first) M*=D; CGAL_NEF_TRACEV(f1);CGAL_NEF_TRACEV(f2);CGAL_NEF_TRACEV(q);CGAL_NEF_TRACEV(r);CGAL_NEF_TRACEV(M); r /= r.content(); f1=f2; f2=r; first=false; } CGAL_NEF_TRACEV(f1.content()); return Polynomial(F)*f1.abs(); } inline void Polynomial::euclidean_div( const Polynomial& f, const Polynomial& g, Polynomial& q, Polynomial& r) { r = f; r.copy_on_write(); int rd=r.degree(), gd=g.degree(), qd; if ( rd < gd ) { q = Polynomial(double(0)); } else { qd = rd-gd+1; q = Polynomial(std::size_t(qd)); } while ( rd >= gd && !(r.is_zero())) { double S = r[rd] / g[gd]; qd = rd-gd; q.coeff(qd) += S; r.minus_offsetmult(g,S,qd); rd = r.degree(); } CGAL_postcondition( f==q*g+r ); } inline void Polynomial::pseudo_div( const Polynomial& f, const Polynomial& g, Polynomial& q, Polynomial& r, double& D) { CGAL_NEF_TRACEN("pseudo_div "<(0); r = f; D = 1; CGAL_postcondition(Polynomial(D)*f==q*g+r); return; } // now we know fd >= gd and f>=g int qd=fd-gd, delta=qd+1, rd=fd; q = Polynomial( std::size_t(delta) ); double G = g[gd]; // highest order coeff of g D = G; while (--delta) D*=G; // D = G^delta Polynomial res = Polynomial(D)*f; CGAL_NEF_TRACEN(" pseudo_div start "<= 0) { double F = res[rd]; // highest order coeff of res double t = F/G; // ensured to be integer by multiplication of D q.coeff(qd) = t; // store q coeff res.minus_offsetmult(g,t,qd); if (res.is_zero()) break; rd = res.degree(); qd = rd - gd; } r = res; CGAL_postcondition(Polynomial(D)*f==q*g+r); CGAL_NEF_TRACEN(" returning "< Polynomial::gcd( const Polynomial& p1, const Polynomial& p2) { CGAL_NEF_TRACEN("gcd("<(double(1)); else return p2.abs(); } if ( p2.is_zero() ) return p1.abs(); Polynomial f1 = p1.abs(); Polynomial f2 = p2.abs(); double f1c = f1.content(), f2c = f2.content(); f1 /= f1c; f2 /= f2c; Polynomial q,r; double M=1,D; bool first = true; while ( ! f2.is_zero() ) { Polynomial::pseudo_div(f1,f2,q,r,D); if (!first) M*=D; CGAL_NEF_TRACEV(f1);CGAL_NEF_TRACEV(f2);CGAL_NEF_TRACEV(q);CGAL_NEF_TRACEV(r);CGAL_NEF_TRACEV(M); r /= r.content(); f1=f2; f2=r; first=false; } CGAL_NEF_TRACEV(f1.content()); return Polynomial(1)*f1.abs(); } } // end namespace Nef }//end namespace CGAL