]> www.ginac.de Git - ginac.git/commitdiff
polynomial: introduce a helper function to divide polynomial by ring element.
authorAlexei Sheplyakov <varg@theor.jinr.ru>
Tue, 14 Oct 2008 06:44:07 +0000 (10:44 +0400)
committerAlexei Sheplyakov <varg@theor.jinr.ru>
Tue, 14 Oct 2008 06:44:07 +0000 (10:44 +0400)
ginac/polynomial/ring_traits.hpp
ginac/polynomial/upoly.hpp

index 10fb172a5550be0626415879e8f0e423c0d4f7b4..540a6bd716e455eb7a084528b0d681ee3c8a08e9 100644 (file)
@@ -10,6 +10,19 @@ static inline cln::cl_I div(const cln::cl_I& x, const cln::cl_I& y)
        return cln::exquo(x, y);
 }
 
        return cln::exquo(x, y);
 }
 
+/// Exact integer division.
+/// Check if y divides x, if yes put the quotient into q, otherwise don't
+/// touch q. Returns true if y divides x and false if not.
+static inline bool div(cln::cl_I& q, const cln::cl_I& x, const cln::cl_I& y)
+{
+       const cln::cl_I_div_t qr = cln::truncate2(x, y);
+       if (zerop(qr.remainder)) {
+               q = qr.quotient;
+               return true;
+       }
+       return false;
+}
+
 static inline cln::cl_I get_ring_elt(const cln::cl_I& sample, const int val)
 {
        return cln::cl_I(val);
 static inline cln::cl_I get_ring_elt(const cln::cl_I& sample, const int val)
 {
        return cln::cl_I(val);
index 3564ae02bc3f80a5cf27c8ccad408c075e86abbf..2e9092f1d47a24ad1888a6af5a881f353f8682c4 100644 (file)
@@ -8,6 +8,7 @@
 #include <stdexcept>
 #include <iterator>
 #include <limits>
 #include <stdexcept>
 #include <iterator>
 #include <limits>
+#include "ring_traits.hpp"
 #include "debug.hpp"
 #include "compiler.h"
 
 #include "debug.hpp"
 #include "compiler.h"
 
@@ -113,6 +114,36 @@ operator*=(T& p, const typename T::value_type& c)
        return p;
 }
 
        return p;
 }
 
+/// Divide the polynomial @a p by the ring element @a c, put the result
+/// into @a r. If @a p is not divisible by @a c @a r is undefined.
+template<typename T> bool divide(T& r, const T& p, const typename T::value_type& c)
+{
+       if (p.empty()) {
+               r.clear();
+               return true;
+       }
+       if (r.size() != p.size())
+               r.resize(p.size());
+       bool divisible = true;
+       for (std::size_t i = p.size(); i-- != 0; ) {
+               divisible = div(r[i], p[i], c);
+               if (!divisible)
+                       break;
+       }
+       return divisible;
+}
+
+template<typename T> bool divide(T& p, const typename T::value_type& c)
+{
+       if (p.empty())
+               return true;
+       T r(p.size());
+       bool divisible = divide(r, p, c);
+       if (divisible)
+               swap(p, r);
+       return divisible;
+}
+
 // Convert Z[x] -> Z/p[x]
 
 static void
 // Convert Z[x] -> Z/p[x]
 
 static void