# Coefficients returned from CoefficientRules

When I used an older version of Mathematica, CoefficientRules returned coefficients as entered, say x^2 +2x -4 y + 13., it returned {{2,0}->1,{1,0}->2,{0,1}->-4,{0,0}->13.} with all coefficients returned as integers except the last one.

I used this to identify non-valid (== non-integral) coefficients in my polynomial.

In version 13 of Mathematica, if I enter one coefficient as non-integral all other integer coefficients are returned as non-inetrgral as well.

I real want to have all coefficients in my polynomials returned as given.

Any suggestions?

Kent

• CoefficientRules[poly // Rationalize] Jun 6, 2022 at 18:42
• @BobHanlon: I think the OP wants the coefficients to be returned as given, not all rationalized. In other words, the desired output is {2, 0} -> 1, {1, 0} -> 2, {0, 1} -> -4, {0, 0} -> 13.}. Jun 6, 2022 at 19:01
• @MichaelSeifert - Then ReplacePart[CoefficientRules[poly // Rationalize], -1 -> ({0, 0} -> (poly /. Thread[Variables[poly] -> 0]))] Jun 6, 2022 at 19:27
• @BobHanlon: That doesn't look like it will work if any term other than the constant term is non-rational. But admittedly the OP only gave us the one use case. Jun 6, 2022 at 19:29

This seems to work, though the indexing is off by one compared to CoefficientRules:

expr = x^2 + 2 x - 4 y + 13.
result = Most[ArrayRules[CoefficientList[expr, {x, y}]]]
(* {{1, 1} -> 13., {1, 2} -> -4, {2, 1} -> 2, {3, 1} -> 1} *)

To regain the original indexing, you can apply the following command:

MapAt[# - 1 &, result, {All, 1}]
(* {{0, 0} -> 13., {0, 1} -> -4, {1, 0} -> 2, {2, 0} -> 1} *)

The ordering of the results is also different; judicious application of SortBy can probably fix this if needed.

Another way:

CoefficientRules[
x^2 + 2 x - 4 y + 13. /. x_Real | x_Complex :> \[FormalA][x],
{x, y}] /. \[FormalA][x_] :> x

(*  {{2, 0} -> 1, {1, 0} -> 2, {0, 1} -> -4, {0, 0} -> 13.}  *)

Here is a function which should reproduce your desired results for any polynomial.

coefficientRulesAlt[polynomial_] :=
Module[{
var, pows, lis,
poly = polynomial},
var = Variables[poly];
pows = Table[{var[[i]], #[[i]]}, {i, Length[var]}] & /@
Tuples[Table[ix, {ix, 0, #}] & /@ Exponent[poly, var]];
lis = Table[
Table[Last@pows[[j]][[i]], {i, Length[pows[[j]]]}] ->
Fold[Coefficient[#1, #2[[1]], #2[[2]]] &, poly, pows[[j]]], {j,
Length[pows]}];
Reverse[If[Last[#] != 0, #, Nothing] & /@ lis]]

Input

coefficientRulesAlt[13. + 2 x + x^2 - 4 y]

Output

{{2, 0} -> 1, {1, 0} -> 2, {0, 1} -> -4, {0, 0} -> 13.}

Input

coefficientRulesAlt[126.357 + 2.1354 z + π*x^20*z^2 - 4 y]

Output

{{1, 0, 0} -> -4, {0, 2, 20} -> π, {0, 1, 0} ->
2.1354, {0, 0, 0} -> 126.357}
• Great, this solves my problem for my coefficient check for my polynomials!
– kent
Jun 9, 2022 at 11:01
• It seems that the behaviour of CoeffcientRules changed sometime between version 10 and 13 of Mathematica. Why it was changed is unclear to me. Anybody?
– kent
Jun 9, 2022 at 11:01