# vpa

Variable-precision arithmetic (arbitrary-precision arithmetic)

Support for character vectors that do not define a number has been removed. Instead, first create symbolic numbers and variables using `sym` and `syms`, and then use operations on them. For example, use ```vpa((1 + sqrt(sym(5)))/2)``` instead of `vpa('(1 + sqrt(5))/2')`.

## Syntax

``vpa(x)``
``vpa(x,d)``

## Description

example

````vpa(x)` uses variable-precision floating-point arithmetic (VPA) to evaluate each element of the symbolic input `x` to at least `d` significant digits, where `d` is the value of the `digits` function. The default value of `digits` is 32.```

example

````vpa(x,d)` uses at least `d` significant digits, instead of the value of `digits`.```

## Examples

### Evaluate Symbolic Inputs with Variable-Precision Arithmetic

Evaluate symbolic inputs with variable-precision floating-point arithmetic. By default, `vpa` calculates values to 32 significant digits.

```syms x p = sym(pi); piVpa = vpa(p)```
```piVpa = 3.1415926535897932384626433832795```
```a = sym(1/3); f = a*sin(2*p*x); fVpa = vpa(f)```
```fVpa = 0.33333333333333333333333333333333*sin(6.283185307179586476925286766559*x)```

Evaluate elements of vectors or matrices with variable-precision arithmetic.

```V = [x/p a^3]; M = [sin(p) cos(p/5); exp(p*x) x/log(p)]; vpa(V) vpa(M)```
```ans = [ 0.31830988618379067153776752674503*x, 0.037037037037037037037037037037037] ans = [ 0, 0.80901699437494742410229341718282] [ exp(3.1415926535897932384626433832795*x), 0.87356852683023186835397746476334*x]```

Note

You must wrap all inner inputs with `vpa`, such as `exp(vpa(200))`. Otherwise the inputs are automatically converted to double by MATLAB®.

### Change Precision Used by `vpa`

By default, `vpa` evaluates inputs to 32 significant digits. You can change the number of significant digits by using the `digits` function.

Approximate the expression `100001/10001` with seven significant digits using `digits`. Save the old value of `digits` returned by `digits(7)`. The `vpa` function returns only five significant digits, which can mean the remaining digits are zeros.

```digitsOld = digits(7); y = sym(100001)/10001; vpa(y)```
```ans = 9.9991```

Check if the remaining digits are zeros by using a higher precision value of `25`. The result shows that the remaining digits are in fact a repeating decimal.

```digits(25) vpa(y)```
```ans = 9.999100089991000899910009```

Alternatively, to override `digits` for a single `vpa` call, change the precision by specifying the second argument.

Find π to 100 significant digits by specifying the second argument.

`vpa(pi,100)`
```ans = 3.141592653589793238462643383279502884197169... 39937510582097494459230781640628620899862803... 4825342117068 ```

Restore the original precision value in `digitsOld` for further calculations.

`digits(digitsOld)`

### Numerically Approximate Symbolic Results

While symbolic results are exact, they might not be in a convenient form. You can use `vpa` to numerically approximate exact symbolic results.

Solve a high-degree polynomial for its roots using `solve`. The `solve` function cannot symbolically solve the high-degree polynomial and represents the roots using `root`.

```syms x y = solve(x^4 - x + 1, x)```
```y = root(z^4 - z + 1, z, 1) root(z^4 - z + 1, z, 2) root(z^4 - z + 1, z, 3) root(z^4 - z + 1, z, 4)```

Use `vpa` to numerically approximate the roots.

`yVpa = vpa(y)`
```yVpa = 0.72713608449119683997667565867496 - 0.43001428832971577641651985839602i 0.72713608449119683997667565867496 + 0.43001428832971577641651985839602i - 0.72713608449119683997667565867496 - 0.93409928946052943963903028710582i - 0.72713608449119683997667565867496 + 0.93409928946052943963903028710582i```

### `vpa` Uses Guard Digits to Maintain Precision

The value of the `digits` function specifies the minimum number of significant digits used. Internally, `vpa` can use more digits than `digits` specifies. These additional digits are called guard digits because they guard against round-off errors in subsequent calculations.

Numerically approximate `1/3` using four significant digits.

`a = vpa(1/3, 4)`
```a = 0.3333```

Approximate the result `a` using 20 digits. The result shows that the toolbox internally used more than four digits when computing `a`. The last digits in the result are incorrect because of the round-off error.

`vpa(a, 20)`
```ans = 0.33333333333303016843```

### Avoid Hidden Round-off Errors

Hidden round-off errors can cause unexpected results.

Evaluate `1/10` with the default 32-digit precision, and then with the 10 digits precision.

```a = vpa(1/10, 32) b = vpa(1/10, 10)```
```a = 0.1 b = 0.1```

Superficially, `a` and `b` look equal. Check their equality by finding `a - b`.

`a - b`
```ans = 0.000000000000000000086736173798840354720600815844403```

The difference is not equal to zero because `b` was calculated with only `10` digits of precision and contains a larger round-off error than `a`. When you find `a - b`, `vpa` approximates `b` with 32 digits. Demonstrate this behavior.

`a - vpa(b, 32)`
```ans = 0.000000000000000000086736173798840354720600815844403```

### `vpa` Restores Precision of Common Double-Precision Inputs

Unlike exact symbolic values, double-precision values inherently contain round-off errors. When you call `vpa` on a double-precision input, `vpa` cannot restore the lost precision, even though it returns more digits than the double-precision value. However, `vpa` can recognize and restore the precision of expressions of the form p/q, pπ/q, (p/q)1/2, 2q, and 10q, where p and q are modest-sized integers.

First, demonstrate that `vpa` cannot restore precision for a double-precision input. Call `vpa` on a double-precision result and the same symbolic result.

```dp = log(3); s = log(sym(3)); dpVpa = vpa(dp) sVpa = vpa(s) d = sVpa - dpVpa```
```dpVpa = 1.0986122886681095600636126619065 sVpa = 1.0986122886681096913952452369225 d = 0.00000000000000013133163257501600766255995767652```

As expected, the double-precision result differs from the exact result at the 16th decimal place.

Demonstrate that `vpa` restores precision for expressions of the form p/q, pπ/q, (p/q)1/2, 2q, and 10q, where p and q are modest sized integers, by finding the difference between the `vpa` call on the double-precision result and on the exact symbolic result. The differences are `0.0` showing that `vpa` restores lost precision in the double-precision input.

```vpa(1/3) - vpa(1/sym(3)) vpa(pi) - vpa(sym(pi)) vpa(1/sqrt(2)) - vpa(1/sqrt(sym(2))) vpa(2^66) - vpa(2^sym(66)) vpa(10^25) - vpa(10^sym(25))```
```ans = 0.0 ans = 0.0 ans = 0.0 ans = 0.0 ans = 0.0```

## Input Arguments

collapse all

Input to evaluate, specified as a number, vector, matrix, multidimensional array, or a symbolic number, vector, matrix, multidimensional array, expression, function, or character vector.

Number of significant digits, specified as an integer. `d` must be greater than 1 and lesser than ${2}^{29}+1$.

## Tips

• `vpa` does not convert fractions in the exponent to floating point. For example, `vpa(a^sym(2/5))` returns `a^(2/5)`.

• `vpa` uses more digits than the number of digits specified by `digits`. These extra digits guard against round-off errors in subsequent calculations and are called guard digits.

• When you call `vpa` on a numeric input, such as `1/3`, `2^(-5)`, or `sin(pi/4)`, the numeric expression is evaluated to a double-precision number that contains round-off errors. Then, `vpa` is called on that double-precision number. For accurate results, convert numeric expressions to symbolic expressions with `sym`. For example, to approximate `exp(1)`, use `vpa(exp(sym(1)))`.

• If the second argument `d` is not an integer, `vpa` rounds it to the nearest integer with `round`.

• `vpa` restores precision for numeric inputs that match the forms p/q, pπ/q, (p/q)1/2, 2q, and 10q, where p and q are modest-sized integers.

• Atomic operations using variable-precision arithmetic round to nearest.

• The differences between variable-precision arithmetic and IEEE Floating-Point Standard 754 are

• Inside computations, division by zero throws an error.

• The exponent range is larger than in any predefined IEEE mode. `vpa` underflows below approximately `10^(-323228496)`.

• Denormalized numbers are not implemented.

• Zeroes are not signed.

• The number of binary digits in the mantissa of a result may differ between variable-precision arithmetic and IEEE predefined types.

• There is only one `NaN` representation. No distinction is made between quiet and signaling `NaN`.

• No floating-point number exceptions are available.

## Version History

Introduced before R2006a