2
$\begingroup$

For applying some function func to the coefficients of a polynomial poly in variables vars, the best way is, indubitably, Collect[poly, vars, func]. However, I find that there are also several separate built-in functions in Mathematica:

  • MonomialListTotal,
  • CoefficientRulesFromCoefficientRules,
  • CoefficientArraysDot,
  • CoefficientListFromDigits,
  • GroebnerBasis`DistributedTermsListGroebnerBasis`FromDistributedTermsList, and
  • Algebra`Polynomial`NestedTermsListAlgebra`Polynomial`FromNestedTermsList.

Certain functions are well-known, while others have never been known before. (If Collect is not allowed, which one would be a better choice?) Note that each pair can implement such a functionality (i.e., Collect[poly, vars, func]). I make a list of these implementations as follows:

(*Way 0: using `MonomialList`*)
Plus @@
     Replace[
          poly ~ MonomialList ~ vars
          ,
          
  With[{n0 = ToExpression /@ StringTemplate["n``"] /@ Range @ Length
                      @ vars, avars = Alternatives @@ vars},
               
   c_ * Times @@ (# ^ Optional /@ Thread @ Pattern[n0 // Evaluate,
                               _]) /; FreeQ[c, avars] -> 
      func[c] * Inner[Power, #, n0, Times] & /@ Subsets
                       @ vars ~ PadRight ~ (Automatic ~ Sequence ~ 1)
           ]
          ,
          {1}
      ]

(*Way 1: using `CoefficientRules`*)
MapAt[func, 
  poly ~ CoefficientRules ~ vars, {All, -1}] ~ FromCoefficientRules ~
      vars

(*Way 2: using `CoefficientArrays`*)
With[{t = CoefficientArrays[poly, vars]},
     WithCleanup[
          SetAttributes[func, Listable];
          If[First @ t =!= 0,
                    First @ t // func
                    ,
                    0
                ] + 
   Total[Fold[Dot, #1, vars ~ ConstantArray ~ #2] & ~ MapIndexed
                      ~ (Most[ArrayRules @@ func @ Threaded @ #1] ~ 
         SparseArray ~ ConstantArray[
                          Length @ vars, #2] & ~ MapIndexed ~ 
       Rest @ t)]
          ,
          ClearAttributes[func, Listable]
      ]
 ]

(*Way 3a: using `CoefficientList`*)
Map[
          If[# === 0,
                #
                ,
                # // func
            ] &
          ,
          poly ~ CoefficientList ~ vars
          ,
          Length @ vars // List
      ] ~ Internal`FromCoefficientList ~ vars

(*Way 3b: using `CoefficientList`*)
Fold[
     Reverse @ #1 ~ FromDigits ~ #2 &
     ,
     Map[
          If[# === 0,
                #
                ,
                # // func
            ] &
          ,
          poly ~ CoefficientList ~ vars
          ,
          Length @ vars // List
      ]
     ,
     vars
 ]

(*Way 4: using `GroebnerBasis`DistributedTermsList`*)
MapAt[func, 
  poly ~ GroebnerBasis`DistributedTermsList ~ vars, {1, ;; ,
        2}] // GroebnerBasis`FromDistributedTermsList

(*Way 5a: using `Algebra`Polynomial`NestedTermsList`*)
System`Private`$SystemFileDir <> 
  System`Dump`fixfile @ "Series`Series`" <>
   "x" // DumpGet
System`Private`$SystemFileDir <> 
  System`Dump`fixfile @ "Algebra`Horner`" <>
       "x" // DumpGet
Block[{t = 
   ExpandAll @ poly ~ Algebra`HornerDump`sparseCoefficientList
         ~ vars, fa},
     fa[x_] := fa[x] =
           If[NumericQ @ First @ x,
                If[ListQ @ Last @ x,
                     {Splice @ Most @ x, fa @@ Rest @ x}
                     ,
                     SubsetMap[func // Map, x, {-1}]
                 ]
                ,
                fa /@ x
            ];
     fa @ t ~ System`SeriesDump`fromSparseCoefficientList ~ vars
 ]

As you can see, some of them are lengthy and uninteresting, which means that the corresponding functions are not really suited for the above aim. So, what is the exact scope of application of each of functions listed above? And are some of them, apart from being a USP, of no use in practice?

$\endgroup$
2
  • 4
    $\begingroup$ I fear that this question could only be answered with opinions, since an authoritative answer would have to come from the designers of the function, at least as it pertains to their intended use. But people are clever, and sometimes functions are put to uses that may have been anticipated by their designers, so even that may not be the final word. Discussions are also discouraged in this forum, which is strictly in Q&A format, so your question may be more appropriate for the Wolfram Community. $\endgroup$
    – MarcoB
    Commented Aug 3, 2023 at 14:34
  • $\begingroup$ @MarcoB I'm not sure. Actually, lots of similar questions (e.g., "Part and Extract?", "OperatorApplied and CurryApplied?", "Array and Table", "TakeLargestBy and MaximalBy?", "Set and SetDelayed?", "Cases, Position, Pick and Select?", and "Defer, Hold, Unevaluated, Inactivate?") were asked here before. I believe that this question can still be as useful as those classical questions in this forum. $\endgroup$
    – user688486
    Commented Aug 4, 2023 at 6:35

0

Your Answer

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

Browse other questions tagged or ask your own question.