7
$\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$
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$
11
$\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$
  • $\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 May 10 '15 at 11:46
  • $\begingroup$ Thank you @Mr.W for the link and the vote. $\endgroup$ – kglr May 10 '15 at 12:00
  • $\begingroup$ @Mr.Wizard thanks for the link, I was able to update that original bug. $\endgroup$ – rcollyer Aug 14 '15 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 Jan 6 '17 at 23:46
8
$\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$
  • $\begingroup$ Why do you prefer Fold to FromDigits or Dot? Also you can drop the second argument of Fold; see: (54784) $\endgroup$ – Mr.Wizard May 10 '15 at 11:44
  • $\begingroup$ Elegant demonstration of a fundamental programming construct. $\endgroup$ – djp May 10 '15 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$ – J. M. is away May 10 '15 at 14:00
  • $\begingroup$ Fair enough. +1 $\endgroup$ – Mr.Wizard May 10 '15 at 14:27
  • $\begingroup$ +1 Answering questions without a viable Mma installation is a NKC. (The C being challenge) $\endgroup$ – Dr. belisarius May 19 '15 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$
  • $\begingroup$ I was expecting direct command :(. This works pretty enough. $\endgroup$ – Serkan Mar 31 '13 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
    $\begingroup$ I think something was copied incorrectly. Specifically Part /@ Range[Length[lst]] does not make sense. $\endgroup$ – Mr.Wizard Aug 14 '15 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 Aug 14 '15 at 15:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.