11
$\begingroup$

Suppose I have a few lists of numbers and want to exponentiate element-wise, then sum up everything into a polynomial.

For example, if I have

a = {1,2,3}
b = {2,4,6}
c = {3,2,1}

I would like to get

poly = xy^2z^3 + x^2y^4z^6 + x^3y^2z

Unfortunately, I am not too familiar with the functional programming style Mathematica is intended to be used for, and I can only write something like

For[i = 1, i < Length[a] + 1, i++,
 term = x^Part[a, i]*y^Part[b, i]*z^Part[c, i];
poly = poly + term;]

As you may expect, this is taking quite a long time to evaluate. Would anybody have any thoughts as to how I would rewrite this to make it more efficient?

$\endgroup$

4 Answers 4

16
$\begingroup$

You can take advantage of listability. As a rule if a function has the Listable attribute listable operations will be faster than other alternatives such as mapping.

{a, b, c} = Transpose[{a, b, c}];
Apply[Plus, x^a*y^b*z^c]

enter image description here

or

{a, b, c} = Transpose[{a, b, c}];
Total[x^a*y^b*z^c]

enter image description here

$\endgroup$
1
  • $\begingroup$ This works very well! Thanks to everyone for all the other superb answers in this thread. $\endgroup$
    – user5392
    Commented Jan 13, 2013 at 22:26
5
$\begingroup$

Using MapThread:

a = {1, 2, 3};
b = {2, 4, 6};
c = {3, 2, 1};

Apply[Plus, MapThread[x^#1*y^#2*z^#3 &, Transpose[{a, b, c}]]]

x^3 y^2 z + x y^2 z^3 + x^2 y^4 z^6

$\endgroup$
5
$\begingroup$
a = {1, 2, 3}; b = {2, 4, 6}; c = {3, 2, 1}; 
Plus @@ Inner[Power, {x, y, z}, Transpose@{a, b, c}, Times]

enter image description here

Tr@Inner[Power, {x, y, z}, Transpose@{a, b, c}, Times]
Total@Inner[Power, {x, y, z}, Transpose@{a, b, c}, Times]
Plus @@ Times @@@ Thread@Power[{x, y, z}, Transpose@{a, b, c}]
Tr[Times @@ Power[{x, y, z}, #] & /@ {a, b, c}]
(* etc. *)

give the same output.

$\endgroup$
3
  • 1
    $\begingroup$ Exactly what I was about to write :-) $\endgroup$ Commented Jan 13, 2013 at 21:47
  • $\begingroup$ @Simon, "de ja vu all over again"? :) $\endgroup$
    – kglr
    Commented Jan 13, 2013 at 21:58
  • $\begingroup$ Obviously a gliche in the matrix =) $\endgroup$
    – nickl-
    Commented Jan 13, 2013 at 22:18
4
$\begingroup$

Let's do it without having to transpose the input lists.

data = {{1, 2, 3}, {2, 4, 6}, {3, 2, 1}};
monomialXYZ[{i_, j_, k_}] := x^i y^j z^k
Apply[Plus, Map[monomialXYZ, data]]

x^3 y^2 z + x y^2 z^3 + x^2 y^4 z^6

The last line of the code can be written more succinctly as

Plus @@ monomialXYZ /@ data
$\endgroup$

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.