9
$\begingroup$

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?

$\endgroup$
1

7 Answers 7

5
$\begingroup$

One straightforward approach is to calculate the answer directly:

Total[{0, 1, 23, 5, 15, 0, 0, 0} x^(Range[8] - 1)]
$\endgroup$
16
$\begingroup$

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.

$\endgroup$
0
16
$\begingroup$

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 *)
$\endgroup$
4
  • $\begingroup$ First mentioned on Stack Exchange here as far as I can tell. +1 for posting it in a place people can find it. $\endgroup$
    – Mr.Wizard
    Commented May 10, 2015 at 11:46
  • $\begingroup$ Thank you @Mr.W for the link and the vote. $\endgroup$
    – kglr
    Commented May 10, 2015 at 12:00
  • $\begingroup$ @Mr.Wizard thanks for the link, I was able to update that original bug. $\endgroup$
    – rcollyer
    Commented Aug 14, 2015 at 15:15
  • $\begingroup$ Just to add on how could this be done with documented functions: rules = (#2 - {1}) -> #1 & @@@ MapIndexed[Rule, cl]; FromCoefficientRules[rules, x]. $\endgroup$
    – corey979
    Commented Jan 6, 2017 at 23:46
9
$\begingroup$

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]
$\endgroup$
6
$\begingroup$

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.

$\endgroup$
6
  • $\begingroup$ Why do you prefer Fold to FromDigits or Dot? Also you can drop the second argument of Fold; see: (54784) $\endgroup$
    – Mr.Wizard
    Commented May 10, 2015 at 11:44
  • $\begingroup$ Elegant demonstration of a fundamental programming construct. $\endgroup$
    – djp
    Commented May 10, 2015 at 12:30
  • $\begingroup$ @Mr. Wizard, re: Fold[], old habits, I guess (I still don't have a computer, much less version 10). Anyway, as I said, this is what is done internally in FromDigits[]; I thought it'd be a nice showcase for Horner. As is well-known, Horner minimizes the number of multiplications necessary for evaluating a polynomial, in contrast to an explicit monomial expansion. $\endgroup$ Commented May 10, 2015 at 14:00
  • $\begingroup$ Fair enough. +1 $\endgroup$
    – Mr.Wizard
    Commented May 10, 2015 at 14:27
  • $\begingroup$ +1 Answering questions without a viable Mma installation is a NKC. (The C being challenge) $\endgroup$ Commented May 19, 2015 at 1:11
3
$\begingroup$

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} *)

$\endgroup$
1
  • $\begingroup$ I was expecting direct command :(. This works pretty enough. $\endgroup$
    – Serkan
    Commented Mar 31, 2013 at 3:59
0
$\begingroup$
mycoeff = {0, 1, 23, 5, 15, 0, 0, 0};
FromCoeff[lst_, x_]:=Plus@@(lst*x^(Part/@Range[Length[lst]]-1));
FromCoeff[mycoeff, x]
$\endgroup$
2
  • 2
    $\begingroup$ I think something was copied incorrectly. Specifically Part /@ Range[Length[lst]] does not make sense. $\endgroup$
    – Mr.Wizard
    Commented Aug 14, 2015 at 0:16
  • 4
    $\begingroup$ I guess it's working now, but Part/@ appears vestigial. Also you are pretty much duplicating bill's Accepted answer. :-/ $\endgroup$
    – Mr.Wizard
    Commented Aug 14, 2015 at 15:08

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.