From cfc52e9e2f080eb37b7496126ad6b2e8fad88f77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 1 Jul 2020 12:30:01 +0200 Subject: [PATCH] fix base_ring for some invariants --- src/sage/rings/invariants/invariant_theory.py | 71 ++++++++++++------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/src/sage/rings/invariants/invariant_theory.py b/src/sage/rings/invariants/invariant_theory.py index 12a4c130abb..71779aac175 100644 --- a/src/sage/rings/invariants/invariant_theory.py +++ b/src/sage/rings/invariants/invariant_theory.py @@ -808,36 +808,57 @@ def _extract_coefficients(self, monomials): ValueError: less monomials were passed than the form actually has """ R = self._ring + Rgens = R.gens() + BR = R.base_ring() if self._homogeneous: variables = self._variables else: - variables = self._variables[0:-1] - indices = [ R.gens().index(x) for x in variables ] - coeffs = dict() - if R.ngens() == 1: + variables = self._variables[:-1] + indices = [Rgens.index(x) for x in variables] + + if len(indices) == len(Rgens): + coeff_ring = BR + else: + coeff_ring = R + + coeffs = {} + if len(Rgens) == 1: # Univariate polynomials - assert indices == [0] - coefficient_monomial_iter = [(c, R.gen(0)**i) for i,c in - enumerate(self._polynomial.padded_list())] - - def index(monomial): - if monomial in R.base_ring(): - return (0,) - return (monomial.exponents()[0],) + + def mono_to_tuple(mono): + return (R(mono).exponents()[0],) + + def coeff_tuple_iter(): + for i, c in enumerate(self._polynomial): + yield (c, (i,)) else: - # Multivariate polynomials - coefficient_monomial_iter = self._polynomial - - def index(monomial): - if monomial in R.base_ring(): - return tuple(0 for i in indices) - e = monomial.exponents()[0] - return tuple(e[i] for i in indices) - for c,m in coefficient_monomial_iter: - i = index(m) - coeffs[i] = c*m + coeffs.pop(i, R.zero()) - result = tuple(coeffs.pop(index(m), R.zero()) // m for m in monomials) - if len(coeffs): + # Multivariate polynomials, mixing variables and coefficients ! + def mono_to_tuple(mono): + # mono is any monomial in the ring R + # keep only the exponents of true variables + mono = R(mono).exponents()[0] + return tuple(mono[i] for i in indices) + + def mono_to_tuple_and_coeff(mono): + # mono is any monomial in the ring R + # separate the exponents of true variables + # and one coefficient monomial + mono = mono.exponents()[0] + true_mono = tuple(mono[i] for i in indices) + coeff_mono = list(mono) + for i in indices: + coeff_mono[i] = 0 + return true_mono, R.monomial(*coeff_mono) + + def coeff_tuple_iter(): + for c, m in self._polynomial: + mono, coeff = mono_to_tuple_and_coeff(m) + yield coeff_ring(c * coeff), mono + + for c, i in coeff_tuple_iter(): + coeffs[i] = c + coeffs.pop(i, coeff_ring.zero()) + result = tuple(coeffs.pop(mono_to_tuple(m), coeff_ring.zero()) for m in monomials) + if coeffs: raise ValueError('less monomials were passed than the form actually has') return result