8

I have an issue with the reconstruction of a polynomial using FromDigits.

The documentation of the function CoefficientList says:

Fold the operation for multivariate polynomials:

CoefficientList[(x + 2 y)^3, {x, y}]

{{0, 0, 0, 8}, {0, 0, 12, 0}, {0, 6, 0, 0}, {1, 0, 0, 0}}

Fold[FromDigits[Reverse[#1], #2] &, %, {x, y}]

x^3 + 6 x^2 y + y^2 (12 x + 8 y)

Now remove the third power and try this minimal example:

CoefficientList[x + 2 y, {x, y}]

{{0, 2}, {1, 0}}

Fold[FromDigits[Reverse[#1], #2] &, %, {x, y}]

1/x + x y

I'm pretty sure I am missing something here, maybe something with small order polynomials as adding anything higher than first order solves the issue.

However in my problem I need to reconstruct a polynomial of order one in one of its variables...

Sorry if this is very simple but I did google it and read through the documentation several times...

Klodd
  • 183
  • 4
  • Welcome to Mathematica.SE! I suggest the following: 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Read the [faq]! 3) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! – Dr. belisarius Nov 24 '14 at 20:04
  • I think you are getting bitten by some internal listability. In any case, `In[236]:= FromDigits[{{1, 0}, 0}, x]

    Out[236]= 1/xis probably not what you are anticipating for the behavior. Now make that second0into the list{0,2}and you get the behavior you are seeing. Again, not what you had wanted. MappingFromDigits` seems like a viable way to go.

    – Daniel Lichtblau Nov 24 '14 at 22:06

4 Answers4

5

You can get the result you want like

 Total@Flatten[ 
    MapIndexed[  #1 x^(#2 - 1)[[1]] y^(#2 - 1)[[2]] & , 
     CoefficientList[(x + 2 y)^3, {x, y}], {2}] ]

I frankly cant follow how the documented procedure is suppoded to work (it seems to be using an undocumented form of FromDigits )

multi variable generalization

 polyFromCL[cl_List, v0_: True] := Module[{v},
     If[TrueQ@v0, v = Array[x, Length[Dimensions[cl]]], v = v0];
        Total@Flatten[
          MapIndexed[
           Times @@ Append[MapThread[ #1^(#2 - 1) & , {v, #2}], #1] &, 
                 cl, {-1}]]]

 polyFromCL[CoefficientList[(x + 2 y)^3 + x y z, {x, y, z}], {x, y, z}]

x^3 + 6 x^2 y + 12 x y^2 + 8 y^3 + x y z

george2079
  • 38,913
  • 1
  • 43
  • 110
  • I could expand easily this solution to my situation where I have 3 variables.

    Total@Flatten[ MapIndexed[#1 x^(#2 - 1)[[1]] y^(#2 - 1)[[2]] z^(#2 - 1)[[3]] &, CoefficientList[(x+2y+3z), {x, y, z}],{3}]]

    – Klodd Nov 24 '14 at 19:17
  • @Klodd Accepting without upvoting will get you 42/6 years of bad luck – Dr. belisarius Nov 24 '14 at 20:59
  • 1
    @belisarius I'm hoping to get a reduced sanction with a late upvote :p I'm new to SE as you have noticed ;) – Klodd Nov 25 '14 at 08:26
  • @Klodd Welcome to the site, again. And hope you keep participating. Very good question, indeed – Dr. belisarius Nov 25 '14 at 12:11
5

I was able to trace the "error" in the docs.

The problem is that the example in the docs isn't general enough. The issue is caused by the two different formats of the list being interpreted by FromDigits[].
Look, here is the "expected" behavior:

FromDigits[{{a, b}, {c, d}, {e, f}}, x]
(* {e + c x + a x^2, f + d x + b x^2} *)

but when only two lists are present, their meaning is different

FromDigits[{{a, b}, {c, d}}, x]
(* {x^(-2 + c) (b + a x), x^(-2 + d) (b + a x)}*)

So, as we need the first form, we just need to ensure more than two lists.Like this:

f[coef_, vars_] := Fold[FromDigits[Reverse[#1], #2] &, 
                        ArrayPad[coef, {{0, 1}, {0, 0}}], 
                        vars] // Expand

So:

s = CoefficientList[ y ^3 + a  y^2 + c x y + b x, {x, y}];
f[s, {x, y}]
s = CoefficientList[a x + b y , {x, y}];
f[s, {x, y}]

(*
 b x + c x y + a y^2 + y^3
 a x + b y
*)
Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453
2

You can also use the undocumented function Internal`FromCoefficientList

Examples:

cl = CoefficientList[(x + 2 y)^3, {x, y}]

{{0, 0, 0, 8}, {0, 0, 12, 0}, {0, 6, 0, 0}, {1, 0, 0, 0}}

fcl = Internal`FromCoefficientList[cl, {x, y}]

x^3 + 6 x^2 y + 12 x y^2 + 8 y^3

FullSimplify[fcl]

(x + 2 y)^3

cl2 = CoefficientList[(x + 2 y)^3 + x y z, {x, y, z}]

{{{0, 0}, {0, 0}, {0, 0}, {8, 0}},
{{0, 0}, {0, 1}, {12, 0}, {0, 0}},
{{0, 0}, {6, 0}, {0, 0}, {0, 0}},
{{1, 0}, {0, 0}, {0, 0}, {0, 0}}}

fcl2 = Internal`FromCoefficientList[cl2, {x, y, z}]

x^3 + 6 x^2 y + 12 x y^2 + 8 y^3 + x y z

FullSimplify[fcl2]

(x + 2 y)^3 + x y z

Note: This approach works both in Version 9.0.1.0 for Windows (64-bit) and 10.1.0 for Linux x86 (64-bit) (Wolfram Programming Cloud).

Usual caveat regarding using undocumented functions apply.

kglr
  • 394,356
  • 18
  • 477
  • 896
0

A recursive algorithm to unfold CoefficientLists of arbitrary dimensions:

polyFromCL[cl_, {}] := cl
polyFromCL[cl_, vars_] :=
  polyFromCL[
    Fold[(#1 First@vars + #2) &, Reverse@cl],
    Rest@vars
  ]

(There must be a way of doing a two dimensional fold.)

poly = a x^5 + (x + 2 y)^3 + x y z + 1;
cl = CoefficientList[poly, {x, y, z}];
polyFromCL[cl, {x, y, z}]
Expand[% - poly]

(* 0 *)
djp
  • 1,493
  • 14
  • 18