X-Git-Url: https://ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Fpolynomial%2Fremainder.h;h=a3f9ae8ef104e3348f42dd325f361529f80fa700;hb=d5b86dd10dd9cba12175d07af0b6edfc9a215e36;hp=3b62ec4a485e470ab8bd57fa6447f3331562d04c;hpb=80b1c3e0ee0e465d56e5c76bef4e52ef2dbc5197;p=ginac.git diff --git a/ginac/polynomial/remainder.h b/ginac/polynomial/remainder.h index 3b62ec4a..a3f9ae8e 100644 --- a/ginac/polynomial/remainder.h +++ b/ginac/polynomial/remainder.h @@ -1,68 +1,36 @@ -#ifndef GINAC_UPOLY_REMAINDER_TCC -#define GINAC_UPOLY_REMAINDER_TCC -#include "upoly.h" -#include "ring_traits.h" -#include "upoly_io.h" -#include "debug.h" +/** @file remainder.h + * + * Functions calculating remainders. */ -namespace GiNaC -{ -/** - * @brief Polynomial remainder for univariate polynomials over fields +/* + * GiNaC Copyright (C) 1999-2015 Johannes Gutenberg University Mainz, Germany * - * Given two univariate polynomials \f$a, b \in F[x]\f$, where F is - * a finite field (presumably Z/p) computes the remainder @a r, which is - * defined as \f$a = b q + r\f$. Returns true if the remainder is zero - * and false otherwise. + * 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 */ -static bool -remainder_in_field(umodpoly& r, const umodpoly& a, const umodpoly& b) -{ - typedef cln::cl_MI field_t; - - if (degree(a) < degree(b)) { - r = a; - return false; - } - // The coefficient ring is a field, so any 0 degree polynomial - // divides any other polynomial. - if (degree(b) == 0) { - r.clear(); - return true; - } - - r = a; - const field_t b_lcoeff = lcoeff(b); - for (std::size_t k = a.size(); k-- >= b.size(); ) { - - // r -= r_k/b_n x^{k - n} b(x) - if (zerop(r[k])) - continue; - field_t qk = div(r[k], b_lcoeff); - bug_on(zerop(qk), "division in a field yield zero: " - << r[k] << '/' << b_lcoeff); +#ifndef GINAC_UPOLY_REMAINDER_H +#define GINAC_UPOLY_REMAINDER_H - // Why C++ is so off-by-one prone? - for (std::size_t j = k, i = b.size(); i-- != 0; --j) { - if (zerop(b[i])) - continue; - r[j] = r[j] - qk*b[i]; - } - bug_on(!zerop(r[k]), "polynomial division in field failed: " << - "r[" << k << "] = " << r[k] << ", " << - "r = " << r << ", b = " << b); +#include "upoly.h" +#include "ring_traits.h" +#include "upoly_io.h" +#include "debug.h" - } +namespace GiNaC { - // Canonicalize the remainder: remove leading zeros. Give a hint - // to canonicalize(): we know degree(remainder) < degree(b) - // (because the coefficient ring is a field), so - // c_{degree(b)} \ldots c_{degree(a)} are definitely zero. - std::size_t from = degree(b) - 1; - canonicalize(r, from); - return r.empty(); -} +bool remainder_in_field(umodpoly& r, const umodpoly& a, const umodpoly& b); /** * @brief Polynomial remainder for univariate polynomials over a ring. @@ -110,7 +78,7 @@ bool remainder_in_ring(T& r, const T& a, const T& b) canonicalize(r); return r.empty(); } -} // namespace GiNaC -#endif // GINAC_UPOLY_REMAINDER_TCC +} // namespace GiNaC +#endif // GINAC_UPOLY_REMAINDER_H