2
$\begingroup$

I ran into a problem with CoefficientRules behaving differently with exact and numerical coefficients, where in the numerical case it behaves as if the entire expression had an N[...] around it, numericizing all numbers, including indices.

E.g.,

CoefficientRules[A[0] x + A[1] y + 1, {x, y}]

works as intended, but

CoefficientRules[A[0] x + A[1] y + 1., {x, y}]

does not, as it has A[0.] and A[1.] in the result.

Is there an easy way to stop this from happening or to convert back the wrong results to their correct form?

Edit: one general workaround I found is to use subscripts such as Subscript[A,0] instead of expressions that could be interpreted as function evaluations. That also works with multiple indices and non-integer parameters, for which some of the other suggested workarounds do not.

$\endgroup$
6
  • 2
    $\begingroup$ I'd call this a bug and report it to Wolfram Support. For comparison, both CoefficientList and CoefficientArrays, which effectively carry out the same task as CoefficientRules but present their result differently, behave in the way you expect, I.e. they do not numericise indices. Perhaps one of those could be used as a workaround as well. $\endgroup$
    – MarcoB
    Commented Dec 28, 2021 at 14:49
  • 2
    $\begingroup$ Maybe set attributes of A to NHoldAll? $\endgroup$ Commented Dec 28, 2021 at 14:58
  • $\begingroup$ Another workaround is just to round indices: CoefficientRules[A[0] x + A[1] y + 1., {x, y}] /. A[n_] :> A[Round[n]] or more generally CoefficientRules[A[0] x + A[1] y + 1., {x, y}] /. f_[n_] :> f[Round[n]] $\endgroup$
    – Bob Hanlon
    Commented Dec 28, 2021 at 15:12
  • $\begingroup$ Kind of a PIA if one of your coefficients is numeric & exact, like 2 or Sqrt[2] or 2/3 etc. $\endgroup$
    – Michael E2
    Commented Dec 28, 2021 at 15:28
  • $\begingroup$ With respect to a bug, a straight Trace[CoefficientRules[A[0] x + A[1] y + 1., {x, y}]] (or traceView2[..]-- look up on site) shows it's intentional. But if so, the docs should point it out, which should be reported/suggested to WRI. $\endgroup$
    – Michael E2
    Commented Dec 28, 2021 at 15:45

1 Answer 1

2
$\begingroup$

I prefer Daniel Lichtblau's workaround, which can be done temporarily:

Block[{A},
 SetAttributes[A, NHoldAll];
 CoefficientRules[A[0] x + A[1] y + 1., {x, y}]    (* A N-protected *)
 ]
CoefficientRules[A[0] x + A[1] y + 1., {x, y}]
(*
  {{1, 0} -> A[0], {0, 1} -> A[1], {0, 0} -> 1.}   (* A N-protected *)
  {{{1, 0} -> A[0.], {0, 1} -> A[1.], {0, 0} -> 1.}
*)

Another way is to use CoefficientList and convert the output to rules:

With[{coeff = 
   SparseArray@CoefficientList[A[0] x + A[1] y + 1., {x, y}]},
 Thread[coeff@"NonzeroPositions" - 1 -> coeff@"NonzeroValues"]
 ]
(*
  {{0, 0} -> 1., {0, 1} -> A[1], {1, 0} -> A[0]}  
*)

With CoefficentList exact numeric coefficients are left intact:

Block[{A},
 SetAttributes[A, NHoldAll];
 CoefficientRules[A[0] x + Sqrt[2] A[1] y + 1., {x, y}]
 ]
(*  {{1, 0} -> A[0], {0, 1} -> 1.41421 A[1], {0, 0} -> 1.}  *)

With[{coeff = 
   SparseArray@
    CoefficientList[A[0] x + Sqrt[2] A[1] y + 1., {x, y}]},
 Thread[coeff@"NonzeroPositions" - 1 -> coeff@"NonzeroValues"]
 ]
(*  {{0, 0} -> 1., {0, 1} -> Sqrt[2] A[1], {1, 0} -> A[0]}  *)
$\endgroup$

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.