9
$\begingroup$

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

$\endgroup$
4
  • $\begingroup$ CoefficientRules[poly // Rationalize] $\endgroup$
    – Bob Hanlon
    Jun 6, 2022 at 18:42
  • $\begingroup$ @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.}. $\endgroup$ Jun 6, 2022 at 19:01
  • $\begingroup$ @MichaelSeifert - Then ReplacePart[CoefficientRules[poly // Rationalize], -1 -> ({0, 0} -> (poly /. Thread[Variables[poly] -> 0]))] $\endgroup$
    – Bob Hanlon
    Jun 6, 2022 at 19:27
  • 1
    $\begingroup$ @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. $\endgroup$ Jun 6, 2022 at 19:29

3 Answers 3

7
$\begingroup$

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.

$\endgroup$
4
$\begingroup$

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.}  *)
$\endgroup$
3
$\begingroup$

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}
$\endgroup$
2
  • 1
    $\begingroup$ Great, this solves my problem for my coefficient check for my polynomials! $\endgroup$
    – kent
    Jun 9, 2022 at 11:01
  • $\begingroup$ 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? $\endgroup$
    – kent
    Jun 9, 2022 at 11:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.