Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split expression into collection of terms

I have a long expression that I would like to split into a collection of terms. For example say I have:

a + b - c + d + 4*e - 3*f

I want to split the expression by addition/subtraction into:

{a, b, -c, d, 4*e, -3*f}

My motivation for this is that I want to deal with the original expression term by term. Is this possible?

Edit: The examples given are VERY simplistic compared to what I'm actually dealing with in Mathematica, it's just that I'm not sure how to write Math around here.

like image 481
V.S. Avatar asked Oct 08 '11 14:10

V.S.


2 Answers

To split the expression, you need to use Level. Level gives you a list of subexpressions and you can specify the level at which you want the subexpressions returned. In this case, you need levelspec 1.

In[1]:= expr = a + b - c + d + 4 e - 3 f;
In[2]:= Level[expr, 1]

Out[2]= {a, b, -c, d, 4 e, -3 f}

An example with a slightly more complicated expression:

In[3]:= expr2 = a^2 + 5 bc/ef - Sqrt[g - h] - Cos[i]/Sin[j + k];
In[4]:= Level[expr2, 1]

Out[4]= {a^2, (5 bc)/ef, -Sqrt[g - h], -Cos[i] Csc[j + k]}
like image 114
abcd Avatar answered Sep 17 '22 21:09

abcd


Since no one else has mentioned it, equivalent to Yoda's Level[expr, 1] construction is to use Apply to replace the head of an expression with List:

In[1]:= expr = a + b - c + d + 4 e - 3 f;

In[2]:= List @@ expr
        Level[expr, 1] == %

Out[2]= {a, b, -c, d, 4 e, -3 f}
Out[3]= True


In[4]:= expr2 = a^2 + 5 bc/ef - Sqrt[g - h] - Cos[i]/Sin[j + k];

In[5]:= List @@ expr2
        Level[expr2, 1] == %

Out[5]= {a^2, (5 bc)/ef, -Sqrt[g - h], -Cos[i] Csc[j + k]}
Out[6]= True

The two methods do basically the same thing and have identical timings (using my version of a average timing function)

In[1]:= SetOptions[TimeAv, Method -> {"MinNum", 80000}, "BlockSize" -> 20000];

In[7]:= List @@ expr // TimeAv

Total wall time is 0.244517, total cpu time is 0.13 
and total time spent evaluating the expression is 0.13

The expression was evaluated 80000 times, in blocks of 20000 runs. This yields
a mean timing of 1.625*10^-6 with a blocked standard deviation of 2.16506*10^-7.

Out[7]= {1.625*10^-6, {a, b, -c, d, 4 e, -3 f}}

In[8]:= Level[expr, 1] // TimeAv

Total wall time is 0.336927, total cpu time is 0.16 
and total time spent evaluating the expression is 0.16

The expression was evaluated 80000 times, in blocks of 20000 runs. This yields 
a mean timing of 2.*10^-6 with a blocked standard deviation of 3.53553*10^-7.

Out[8]= {2.*10^-6, {a, b, -c, d, 4 e, -3 f}}
like image 32
Simon Avatar answered Sep 20 '22 21:09

Simon