## Using Mathematica » Useful Features

## Symbolic Algebra

As is explained more fully in the Mathematica Programming section, the language Mathematica is built around is almost 100% symbolic, which makes it perfect for algebraic manipulations.

One of the simplest examples of things one can do in Mathematica is generate and combine polynomials:

` ````
simplePolynomial[var_,order_]:=
Total@Table[RandomInteger[10]*Power[var,n],{n,order}];
```

We'll make a few of these polynomials and add them:

` ````
pX1=simplePolynomial[x,2]
pX2=simplePolynomial[x,2]
pX1+pX2
```

` ``6 x+6 x^2`

` ``8 x+9 x^2`

` ``14 x+15 x^2`

This works just as well at any polynomial order. Here we'll add five randomly generated polynomials of order less than or equal to `15`

.

` ``Array[(simplePolynomial[x, RandomInteger[15]])&, 5]//Total`

` ``22 x+26 x^2+15 x^3+28 x^4+10 x^5+9 x^6+12 x^7+13 x^8+19 x^9+11 x^10+9 x^11+13 x^12+6 x^13+4 x^14`

Here's that again, but formatted nicer:

$$4 x^{14}+6 x^{13}+13 x^{12}+9 x^{11}+11 x^{10}+19 x^9+13 x^8+12 x^7+9 x^6+10 x^5+28 x^4+15 x^3+26 x^2+22 x$$

For those interested, the `&`

specifies that what comes before should be treated as a function, but absent any variables we simply get our expression as a result.

### Simplify

For more complex things we'll need to explicitly simplify them:

` ````
sphericalHarmonicSum=
Total@
Array[
SphericalHarmonicY[RandomInteger[5], RandomInteger[5], θ, ϕ]&,
5]
```

We can then have Mathematica simplify this expression for us more:

` ``Simplify[sphericalHarmonicSum]`

$$\frac{1}{64} \sqrt{\frac{3}{2 \pi }} e^{i \phi } \sin (\theta ) \left(2 \left(\sqrt{11}+4\right) \sqrt{35} e^{i \phi } \sin (2 \theta )+3 \sqrt{385} e^{i \phi } \sin (4 \theta )-32\right)$$

Sometimes we also need to use the function `FullSimplify`

to get everything simplified:

` ``FullSimplify[sphericalHarmonicSum]`

$$\frac{1}{32} \sqrt{\frac{3}{2 \pi }} e^{i \phi } \sin (\theta ) \left(-16+\sqrt{35} e^{i \phi } \sin (2 \theta ) \left(3 \sqrt{11} \cos (2 \theta )+\sqrt{11}+4\right)\right)$$

It often makes sense to go for `Simplify`

over `FullSimplify`

, despite the fact that we can get more simplification out of `FullSimplify`

, because sometimes the `Simplify`

is all we need to see a pattern ourselves, while `FullSimplify`

can over-simplify and obliterate that pattern.

It's good to keep in mind that while Mathematica may know more than we do, we're still smarter than it is.

### Solve

Mathematica can also solve equations for us. We'll try this on a nice quartic polynomial:

` ``polynomialInX=simplePolynomial[x, 4]`

$$6 x^4+3 x^3+5 x^2+6 x$$

Note that there's no nice way to find the roots of this polynomial by hand. But Mathematica doesn't mind:

` ``Solve[polynomialInX==0,x]`

` ````
{
{x->0},
{x->1/6 (-1-9/(-94 + Sqrt[9565])^(1/3)+(-94 + Sqrt[9565])^(1/3))},
{x->-1/6+(3 (1 + I Sqrt[3]))/(4 (-94 + Sqrt[9565])^(1/3))-1/12 (1-I Sqrt[3]) (-94 + Sqrt[9565])^(1/3)},
{x->-1/6+(3 (1 - I Sqrt[3]))/(4 (-94 + Sqrt[9565])^(1/3))-1/12 (1+I Sqrt[3]) (-94 + Sqrt[9565])^(1/3)}
}
```

Here's one of those solutions in easier-to-read form:

$$\frac{1}{6} \left(\sqrt[3]{\sqrt{9565}-94}-\frac{9}{\sqrt[3]{\sqrt{9565}-94}}-1\right)$$

As mentioned before, Mathematica knows more math than any of us. It sees a quartic polynomial and knows that by the fundamental theorem of algebra there are four solutions to this equation, we just might need to find complex solutions.

Usually this isn't what we want, unfortunately. Happily Mathematica can dumb itself down for us.

` ``Solve[polynomialInX==0,x,Reals]`

` ``{ {x->0},{x->Root[6+5 #1+3 #1^2+6 #1^3&,1]} }`

Notice that we get this odd `Root`

expression. That's the way Mathematica represents a perfectly exact root. We can get its numerical one of two ways. Either we make the equation inexact:

` ``Solve[polynomialInX==0., x, Reals]`

` ``{ {x->-0.867733324263096`},{x->0} }`

Or we numericize after the fact:

` ``N[Solve[polynomialInX==0,x,Reals],6]`

` ``{ {x->0},{x->-0.8677333242630958819`6.} }`

One useful thing to know with `Solve`

is why the results are returned so oddly. Each list is a different solution, which is more important with multivariate equations, which we'll get to, but first let's see a nice way to get out our solutions in a simple list:

` ``x/.N[Solve[polynomialInX==0,x,Reals],6]`

` ``{0,-0.8677333242630958819`6.}`

The `/.`

is an alias for `ReplaceAll`

, which is described in more detail later in the Replacement Patterns section. For now let's just note that any time it sees `var`

on the left hand side it looks for `var->val`

on the right hand side and replaces `var`

with that.

Now let's also see how we can plot these solutions:

` ````
Show[
Plot[polynomialInX,{x,-2,2}],
ListPlot[Table[{x,0},
{x,x/.Solve[polynomialInX==0.,x,Reals]}]]
]
```

We have to use `ListPlot`

to plot our discrete solutions, but we can see we get the result we expect.

We could even write a function that will solve the equation for an arbitrary value and plot the result:

` ````
solveAndPlot[eqInX_,val_]:=
Show[
Plot[eqInX,{x,-2,2}],
ListPlot[Table[{x,val},
{x,x/.Solve[eqInX==(1.val),x,Reals]}]],
PlotLabel->
Row@{
HoldForm[eqInX==val]," @ ",
Row@Riffle[(x/.Solve[eqInX==(1.val),x,Reals]),", "]
}
];
```

Calling this on our solution:

` ``solveAndPlot[polynomialInX,50]`

But that's getting distracted, I suppose.

### Multivariate Solve

Let's move to multivariate equations now:

` ``polynomialInXandY=simplePolynomial[x,3]+simplePolynomial[y,3]`

` ``8 x+2 x^2+2 y+10 y^2+8 y^3`

$$2 x^2+8 x+8 y^3+10 y^2+2 y$$

It can still solve this equation, although as it will admit, it may miss some solutions.

` ``Solve[polynomialInXandY == 0,{x,y}, Reals]`

` ``{ {x->ConditionalExpression[-2-Sqrt[4 - y - 5 y^2 - 4 y^3],y<1/12 (-5+(829 - 6 Sqrt[19029])^(1/3)+(829 + 6 Sqrt[19029])^(1/3))]},{x->ConditionalExpression[-2+Sqrt[4 - y - 5 y^2 - 4 y^3],y<1/12 (-5+(829 - 6 Sqrt[19029])^(1/3)+(829 + 6 Sqrt[19029])^(1/3))]},{x->-2-√(4+1/12 (5-(829 - 6 Sqrt[19029])^(1/3)-(829 + 6 Sqrt[19029])^(1/3))-5/144 (-5 + (829 - 6 Sqrt[19029])^(1/3) + (829 + 6 Sqrt[19029])^(1/3))^2-1/432 (-5 + (829 - 6 Sqrt[19029])^(1/3) + (829 + 6 Sqrt[19029])^(1/3))^3),y->1/12 (-5+(829 - 6 Sqrt[19029])^(1/3)+(829 + 6 Sqrt[19029])^(1/3))} }`

Here's one of the branches in human-readable form:

$$-\sqrt{-\frac{1}{432} \left(\sqrt[3]{6 \sqrt{19029}+829}+\sqrt[3]{829-6 \sqrt{19029}}-5\right)^3-\frac{5}{144} \left(\sqrt[3]{6 \sqrt{19029}+829}+\sqrt[3]{829-6 \sqrt{19029}}-5\right)^2+\frac{1}{12} \left(-\sqrt[3]{6 \sqrt{19029}+829}-\sqrt[3]{829-6 \sqrt{19029}}+5\right)+4}-2$$

Note that it also gives us these odd `ConditionalExpression`

statements. This is because the solution could branch depending on how `x`

and `y`

interplay. Let's just get take one of these solutions:

` ````
conditionalSoln=First[x/.Solve[polynomialInXandY == 0.,{x,y}, Reals]];
N[conditionalSoln]
```

` ``ConditionalExpression[-2.`-1.` Sqrt[4. - 1. y - 5. y^2 - 4. y^3],y<0.6609358769285026`]`

And plot it:

` ``Plot[conditionalSoln,{y,-1,1},PlotLabel->"Value of X for given Y"]`

We can force a given branch of this conditional expression, however, by telling Mathematica what it can assume.

### Assumptions

When Mathematica simplifies an expression it checks what we've told it to about the expression. It does that by looking at the value of the variable `$Assumptions`

` ``$Assumptions`

` ``True`

This is the default value. But we can make it assume things for us. Let's assume that `y`

satifies our `ConditionalExpression`

. First we set the `Assumptions`

:

` ``$Assumptions=y<.5`

` ``y<0.5``

Now Mathematica will use these when solving:

` ``xAndyRoots={x, y}/.Solve[polynomialInXandY == 0, {x, y}, Reals]//First//Simplify`

` ``{-2-Sqrt[4 - y - 5 y^2 - 4 y^3],y}`

And when we're done we simply reset the `$Assumptions`

variable. We can also apply `$Assumptions`

to a single `Simplify`

expression or similar, but I will leave that to you to read up on.