9

I have numbers in vector notation. I need to get polynomial notation from them.

My numbers are {0, 1, 23, 5, 15, 0, 0, 0}. I want to get $x + 23x^2 + 5x^3 + 15x^4$ from this list.

How can I get that polynomial?

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
Serkan
  • 183
  • 4
  • Related question: http://mathematica.stackexchange.com/questions/21340/dynamic-application-of-several-polynomials – Michael E2 Mar 31 '13 at 18:37

7 Answers7

16

The following (taken from the Mathematica documentation) will do what you ask.

Expand[FromDigits[Reverse[{0, 1, 23, 5, 15, 0, 0, 0}], x]]

x + 23 x^2 + 5 x^3 + 15 x^4

I found the needed code in Properties & Relations section of the documentation page on CoefficientList. In general, it is a good idea to look for information on inverses in the Properties & Relations section of any function of interest.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
15

The undocumented function Internal`FromCoefficientList is as close as one would get to InverseCoefficientList.

Examples:

cl = {0, 1, 23, 5, 15, 0, 0, 0};
Internal`FromCoefficientList[cl, x]

x + 23 x^2 + 5 x^3 + 15 x^4

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

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

FullSimplify[Internal`FromCoefficientList[cl2, {x, y}]]

(1 + x + 2 y)^2

See also: this answer by Adam Strzebonski (thanks: Mr. Wizard for the reference)

Timings using @Mr.Wizard's set-up and timeAvg:

n = 5000;
c = RandomInteger[30, n];

Expand[Fold[(#1 \[FormalX] + #2) &, 0, Reverse[c]]] // timeAvg  (* 3.250000 *)
Expand@FromDigits[Reverse@c,  x] // timeAvg                     (* 0.039375 *)
MapIndexed[#1*x^(#2 - 1) &, c] // Total // timeAvg              (* 0.019375 *)
Total[c*x^(Range@n - 1)] // timeAvg                             (* 0.005375 *)
c.(x^Range[0, n - 1]) // timeAvg                                (* 0.003875 *)
Internal`FromCoefficientList[c, x] // timeAvg                   (* 0.003500 *)
kglr
  • 394,356
  • 18
  • 477
  • 896
9

Dot can be very efficient here:

c.(x^Range[0, Length@c - 1])
x + 23 x^2 + 5 x^3 + 15 x^4

Comparative timings:

n = 5000;
c = RandomInteger[30, n];

SetAttributes[timeAvg, HoldFirst]
timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}]

Expand @ FromDigits[Reverse@c, x] // timeAvg
Total[c * x^(Range@n - 1)] // timeAvg
MapIndexed[#1*x^(#2 - 1) &, c] // Total // timeAvg
c.(x^Range[0, n - 1]) // timeAvg

0.03616

0.004992

0.01744

0.003616

I also like this formulation though it is not quite as fast:

c.Array[x^# &, n, 0]
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
6

I vastly prefer using Horner for reconstructing polynomials from their coefficients. To wit:

Fold[(#1 \[FormalX] + #2) &, 0, Reverse[{0, 1, 23, 5, 15, 0, 0, 0}]] // Expand

returns your polynomial. In fact, this is effectively what FromDigits[] does internally for integer digits. Removing the Expand[] yields what would've been the result of applying HornerForm[] to the polynomial.

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
5

One straightforward approach is to calculate the answer directly:

Total[{0, 1, 23, 5, 15, 0, 0, 0} x^(Range[8] - 1)]
bill s
  • 68,936
  • 4
  • 101
  • 191
3

How about this?

MapIndexed[#1*x^(#2 - 1) &, {0, 1, 23, 5, 15, 0, 0, 0}] // Total

(* {x + 23 x^2 + 5 x^3 + 15 x^4} *)

yulinlinyu
  • 4,815
  • 2
  • 29
  • 36
0
mycoeff = {0, 1, 23, 5, 15, 0, 0, 0};
FromCoeff[lst_, x_]:=Plus@@(lst*x^(Part/@Range[Length[lst]]-1));
FromCoeff[mycoeff, x]
  • 2
    I think something was copied incorrectly. Specifically Part /@ Range[Length[lst]] does not make sense. – Mr.Wizard Aug 14 '15 at 00:16
  • 4
    I guess it's working now, but Part/@ appears vestigial. Also you are pretty much duplicating bill's Accepted answer. :-/ – Mr.Wizard Aug 14 '15 at 15:08