Documentation

## Solve Equations Numerically

The Symbolic Math Toolbox™ offers both numeric and symbolic equation solvers. For a comparison of numeric and symbolic solvers, please see Select Numeric or Symbolic Solver. An equation or a system of equations can have multiple solutions. To find these solutions numerically, use the function `vpasolve`. For polynomial equations, `vpasolve` returns all solutions. For nonpolynomial equations, `vpasolve` returns the first solution it finds. This shows you how to use `vpasolve` to find solutions to both polynomial and nonpolynomial equations, and how to obtain these solutions to arbitrary precision.

### Find All Roots of a Polynomial Function

Use `vpasolve` to find all the solutions to function $f\left(x\right)=6{x}^{7}-2{x}^{6}+3{x}^{3}-8$.

```syms f(x) f(x) = 6*x^7-2*x^6+3*x^3-8; sol = vpasolve(f)```
```sol = 1.0240240759053702941448316563337 - 0.88080620051762149639205672298326 + 0.50434058840127584376331806592405i - 0.88080620051762149639205672298326 - 0.50434058840127584376331806592405i - 0.22974795226118163963098570610724 + 0.96774615576744031073999010695171i - 0.22974795226118163963098570610724 - 0.96774615576744031073999010695171i 0.7652087814927846556172932675903 + 0.83187331431049713218367239317121i 0.7652087814927846556172932675903 - 0.83187331431049713218367239317121i ```

`vpasolve` returns seven roots of the function, as expected, because the function is a polynomial of degree seven.

### Find Zeros of a Nonpolynomial Function Using Search Ranges and Starting Points

Consider the function $f\left(x\right)={e}^{\left(x/7\right)}\mathrm{cos}\left(2x\right)$. A plot of the function reveals periodic zeros, with increasing slopes at the zero points as `x` increases.

```syms x h = fplot(exp(x/7)*cos(2*x),[-2 25]); grid on``` Use `vpasolve` to find a zero of the function `f`. Note that `vpasolve` returns only one solution of a nonpolynomial equation, even if multiple solutions exist. On repeated calls, `vpasolve` returns the same result, even if multiple zeros exist.

```f = exp(-x/20)*cos(2*x); for i = 1:3 vpasolve(f,x) end ```
```ans = 19.634954084936207740391521145497 ans = 19.634954084936207740391521145497 ans = 19.634954084936207740391521145497```

To find multiple solutions, set the option `random` to `true`. This makes `vpasolve` choose starting points randomly. For information on the algorithm that chooses random starting points, see Algorithms on the `vpasolve` page.

```for i = 1:3 vpasolve(f,x,'random',true) end```
```ans = -226.98006922186256147892598444194 ans = 98.174770424681038701957605727484 ans = 58.904862254808623221174563436491```

To find a zero close to x = 10 and to x = 1000, set the starting point to `10`, and then to `1000`.

```vpasolve(f,x,10) vpasolve(f,x,1000)```
```ans = 10.210176124166828025003590995658 ans = 999.8118620049516981407362567287```

To find a zero in the range $15\le x\le 25$, set the search range to `[15 25]`.

`vpasolve(f,x,[15 25])`
```ans = 21.205750411731104359622842837137```

To find multiple zeros in the range `[15 25]`, you cannot call `vpasolve` repeatedly as it returns the same result on each call, as previously shown. Instead, set `random` to `true` in conjunction with the search range.

```for i = 1:3 vpasolve(f,x,[15 25],'random',true) end```
```ans = 21.205750411731104359622842837137 ans = 16.493361431346414501928877762217 ans = 16.493361431346414501928877762217```

If you specify the `random` option while also specifying a starting point, `vpasolve` warns you that the two options are incompatible.

`vpasolve(f,x,15,'random',true)`
```Warning: 'Random' has no effect because all variables have a starting value. > In sym/vpasolve (line 168) ans = 14.922565104551517882697556070578```

Create the function `findzeros` below to systematically find all zeros for `f` in a given search range, within the error tolerance. It starts with the input search range and calls `vpasolve` to find a zero. Then, it splits the search range into two around the zero’s value, and recursively calls itself with the new search ranges as inputs to find more zeros. The first input is the function, the second input is the range, and the optional third input allows you to specify the error between a zero and the higher and lower bounds generated from it.

The function is explained section by section here.

Declare the function with the two inputs and one output.

`function sol = findzeros(f,range,err)`

If you do not specify the optional argument for error tolerance, `findzeros` sets `err` to `0.001`.

```if nargin < 2 err = 1e-3; end ```

Find a zero in the search range using `vpasolve`.

`sol = vpasolve(f,range);`

If `vpasolve` does not find a zero, exit.

```if(isempty(sol)) return```

If `vpasolve` finds a zero, split the search range into two search ranges above and below the zero.

```else lowLimit = sol-err; highLimit = sol+err; ```

Call `findzeros` with the lower search range. If `findzeros` returns zeros, copy the values into the solution array and sort them.

``` temp = findzeros(f,[range(1) lowLimit],1); if ~isempty(temp) sol = sort([sol temp]); end```

Call `findzeros` with the higher search range. If `findzeros` returns zeros, copy the values into the solution array and sort them.

``` temp = findzeros(f,[highLimit range(2)],1); if ~isempty(temp) sol = sort([sol temp]); end return end end```

The entire function `findzeros` is as follows.

```function sol = findzeros(f,range,err) if nargin < 3 err = 1e-3; end sol = vpasolve(f,range); if(isempty(sol)) return else lowLimit = sol-err; highLimit = sol+err; temp = findzeros(f,[range(1) lowLimit],1); if ~isempty(temp) sol = sort([sol temp]); end temp = findzeros(f,[highLimit range(2)],1); if ~isempty(temp) sol = sort([sol temp]); end return end end```

Call `findzeros` with search range ```[10 20]``` to find all zeros in that range for ```f(x) = exp(-x/20)*cos(2*x)```, within the default error tolerance.

```syms f(x) f(x) = exp(-x/20)*cos(2*x); findzeros(f,[10 20])```
```ans = [ 10.210176124166828025003590995658, 11.780972450961724644234912687298,... 13.351768777756621263466234378938, 14.922565104551517882697556070578,... 16.493361431346414501928877762217, 18.064157758141311121160199453857,... 19.634954084936207740391521145497]```

### Obtain Solutions to Arbitrary Precision

Use `digits` to set the precision of the solutions. By default, `vpasolve` returns solutions to a precision of 32 significant figures. Use `digits` to increase the precision to 64 significant figures. When modifying `digits`, ensure that you save its current value so that you can restore it.

```f = exp(x/7)*cos(2*x); vpasolve(f) digitsOld = digits; digits(64) vpasolve(f) digits(digitsOld)```
```ans = -7.0685834705770347865409476123789 ans = -7.068583470577034786540947612378881489443631148593988097193625333 ```

### Solve Multivariate Equations Using Search Ranges

Consider the following system of equations.

`$\begin{array}{l}z=10\left(\mathrm{cos}\left(x\right)+\mathrm{cos}\left(y\right)\right)\\ z=x+{y}^{2}-0.1{x}^{2}y\\ x+y-2.7=0\end{array}$`

A plot of the equations for 0 ≤ x ≤ 2.5 and 0 ≤ x ≤ 2.5 shows that the three surfaces intersect in two points. To better visualize the plot, use `view`. To scale the colormap values, use `caxis`.

```syms x y z eqn1 = z == 10*(cos(x) + cos(y)); eqn2 = z == x+y^2-0.1*x^2*y; eqn3 = x+y-2.7 == 0; equations = [eqn1 eqn2 eqn3]; fimplicit3(equations) axis([0 2.5 0 2.5 -20 10]) title('System of Multivariate Equations') view(69, 28) caxis([-15 10])``` Use `vpasolve` to find a point where the surfaces intersect. The function `vpasolve` returns a structure. To access the solution, index into the structure.

```sol = vpasolve(equations); [sol.x sol.y sol.z]```
`ans = $\left(\begin{array}{ccc}2.3697477224547979209101337160174& 0.33025227754520207908986628398261& 2.2933543768232277431243854708612\end{array}\right)$`

To search a region of the solution space, specify search ranges for the variables. If you specify the ranges $0\le x\le 1.5$ and $1.5\le y\le 2.5$, then `vpasolve` function searches the bounded area shown in the picture. Use `vpasolve` to find a solution for this search range$0\le x\le 1.5$ and $1.5\le y\le 2.5$. To omit a search range for `z`, set the search range to `[NaN NaN]`.

```vars = [x y z]; range = [0 1.5; 1.5 2.5; NaN NaN]; sol = vpasolve(equations, vars, range); [sol.x sol.y sol.z]```
`ans = $\left(\begin{array}{ccc}0.91062661725633361176950031551069& 1.7893733827436663882304996844893& 3.9641015721356254724107884666807\end{array}\right)$`

To find multiple solutions, you can set the `random` option to `true`. This makes `vpasolve` use random starting points on successive runs. The `random` option can be used in conjunction with search ranges to make `vpasolve` use random starting points within a search range. Because `random` selects starting points randomly, the same solution might be found on successive calls. Call `vpasolve` repeatedly to ensure you find both solutions.

```clear sol range = [0 3; 0 3; NaN NaN]; for i = 1:5 temp = vpasolve(equations, vars, range, 'random', true); sol(i,1) = temp.x; sol(i,2) = temp.y; sol(i,3) = temp.z; end sol```
```sol =  $\left(\begin{array}{ccc}0.91062661725633361176950031551069& 1.7893733827436663882304996844893& 3.9641015721356254724107884666807\\ 2.3697477224547979209101337160174& 0.33025227754520207908986628398261& 2.2933543768232277431243854708612\\ 0.91062661725633361176950031551069& 1.7893733827436663882304996844893& 3.9641015721356254724107884666807\\ 0.91062661725633361176950031551069& 1.7893733827436663882304996844893& 3.9641015721356254724107884666807\\ 0.91062661725633361176950031551069& 1.7893733827436663882304996844893& 3.9641015721356254724107884666807\end{array}\right)$```

Plot the equations. Superimpose the solutions as a scatter plot of points with yellow `X` markers using `scatter3`. To better visualize the plot, make two of the surfaces transparent using `alpha`. Scale the colormap to the plot values using `caxis`, and change the perspective using `view`.

`vpasolve` finds solutions at the intersection of the surfaces formed by the equations as shown.

```clf ax = axes; h = fimplicit3(equations); h(2).FaceAlpha = 0; h(3).FaceAlpha = 0; axis([0 2.5 0 2.5 -20 10]) hold on scatter3(sol(:,1),sol(:,2),sol(:,3),600,'yellow','X','LineWidth',2) title('Randomly found solutions in specified search range') cz = ax.Children; caxis([0 20]) view(69,28) hold off``` #### Mathematical Modeling with Symbolic Math Toolbox

Get examples and videos