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$
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$
  • $\begingroup$ This works very well! Thanks to everyone for all the other superb answers in this thread. $\endgroup$ – user5392 Jan 13 '13 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$
  • 1
    $\begingroup$ Exactly what I was about to write :-) $\endgroup$ – Simon Woods Jan 13 '13 at 21:47
  • $\begingroup$ @Simon, "de ja vu all over again"? :) $\endgroup$ – kglr Jan 13 '13 at 21:58
  • $\begingroup$ Obviously a gliche in the matrix =) $\endgroup$ – nickl- Jan 13 '13 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, privacy policy and cookie policy

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