]> www.ginac.de Git - ginac.git/blobdiff - ginac/polynomial/mod_gcd.cpp
Happy New Year!
[ginac.git] / ginac / polynomial / mod_gcd.cpp
index 8aa84808c1f64a5975086eaa743d78c93f4e4455..75a7dcb69f49e3d0ec25a3137b189d6c532f2ae8 100644 (file)
@@ -1,13 +1,37 @@
-#include "upoly.hpp"
-#include "gcd_euclid.tcc"
-#include "cra_garner.hpp"
-#include <cln/random.h>
+/** @file mod_gcd.cpp
+ *
+ *  Implementation of modular GCD. */
+
+/*
+ *  GiNaC Copyright (C) 1999-2020 Johannes Gutenberg University Mainz, Germany
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "upoly.h"
+#include "gcd_euclid.h"
+#include "cra_garner.h"
+#include "debug.h"
+
 #include <cln/numtheory.h>
+#include <cln/random.h>
 #include <stdexcept>
-#include "debug.hpp"
+#include <algorithm>
+
+namespace GiNaC {
 
-namespace GiNaC
-{
 /**
  * @brief Remove the integer content from univariate polynomials A and B.
  *
@@ -104,8 +128,18 @@ void mod_gcd(upoly& result, upoly A, upoly B)
        ring_t q(0);
        upoly H;
 
-       ring_t p(2);
+       int count = 0;
+       const ring_t p_threshold = ring_t(1) << (8*sizeof(void *));
+       ring_t p = isqrt(std::min(max_coeff(A), max_coeff(B)));
        while (true) {
+               if (count >= 8) {
+                       count = 0;
+                       if (p < p_threshold)
+                               p <<= 1;
+                       else
+                               p = p + (p >> 4);
+               } else 
+                       ++count;
                find_next_prime(p, g);
 
                // Map the polynomials onto Z/p[x]
@@ -162,4 +196,3 @@ void mod_gcd(upoly& result, upoly A, upoly B)
 }
 
 } // namespace GiNaC
-