vpa

Variable-precision arithmetic (arbitrary-precision arithmetic)

Description

example

xVpa = vpa(x) uses variable-precision arithmetic (arbitrary-precision floating-point numbers) 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

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

Examples

collapse all

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

p = sym(pi);
pVpa = vpa(p)
pVpa = $3.1415926535897932384626433832795$
syms x
a = sym(1/3);
f = a*sin(2*p*x);
fVpa = vpa(f)
fVpa = $0.33333333333333333333333333333333 \mathrm{sin}\left(6.283185307179586476925286766559 x\right)$

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

V = [x/p a^3];
VVpa = vpa(V)
VVpa = $\left(\begin{array}{cc}0.31830988618379067153776752674503 x& 0.037037037037037037037037037037037\end{array}\right)$
M = [sin(p) cos(p/5); exp(p*x) x/log(p)];
MVpa = vpa(M)
MVpa =

$\left(\begin{array}{cc}0& 0.80901699437494742410229341718282\\ {\mathrm{e}}^{3.1415926535897932384626433832795 x}& 0.87356852683023186835397746476334 x\end{array}\right)$

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;
yVpa = vpa(y)
yVpa = $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 zeros that are part of a repeating decimal.

digits(25)
yVpa = vpa(y)
yVpa = $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.

pVpa = vpa(pi,100)
pVpa = $3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068$

Restore the original precision value in digitsOld for further calculations.

digits(digitsOld)

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 =

$\left(\begin{array}{c}\mathrm{root}\left({z}^{4}-z+1,z,1\right)\\ \mathrm{root}\left({z}^{4}-z+1,z,2\right)\\ \mathrm{root}\left({z}^{4}-z+1,z,3\right)\\ \mathrm{root}\left({z}^{4}-z+1,z,4\right)\end{array}\right)$

Use vpa to numerically approximate the roots.

yVpa = vpa(y)
yVpa =

$\left(\begin{array}{c}0.72713608449119683997667565867496-0.43001428832971577641651985839602 \mathrm{i}\\ 0.72713608449119683997667565867496+0.43001428832971577641651985839602 \mathrm{i}\\ -0.72713608449119683997667565867496-0.93409928946052943963903028710582 \mathrm{i}\\ -0.72713608449119683997667565867496+0.93409928946052943963903028710582 \mathrm{i}\end{array}\right)$

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.

aVpa = vpa(a,20)
aVpa = $0.33333333333303016843$

Hidden round-off errors can cause unexpected results.

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

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

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

roundoff = a - b
roundoff = $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.

roundoff = a - vpa(b,32)
roundoff = $0.000000000000000000086736173798840354720600815844403$

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 $\frac{\mathit{p}}{\mathit{q}}$, $\frac{\mathit{p}\pi }{\mathit{q}}$, ${\left(\frac{\mathit{p}}{\mathit{q}}\right)}^{\frac{1}{2}}$, ${2}^{\mathit{q}}$, and ${10}^{\mathit{q}}$, where $\mathit{p}$ and $\mathit{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)
dpVpa = $1.0986122886681095600636126619065$
sVpa = vpa(s)
sVpa = $1.0986122886681096913952452369225$
d = sVpa - dpVpa
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 $\frac{\mathit{p}}{\mathit{q}}$, $\frac{\mathit{p}\pi }{\mathit{q}}$, ${\left(\frac{\mathit{p}}{\mathit{q}}\right)}^{\frac{1}{2}}$, ${2}^{\mathit{q}}$, and ${10}^{\mathit{q}}$, where $\mathit{p}$ and $\mathit{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 for the double-precision input.

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

Since R2022b

Create a symbolic expression S that represents $\mathrm{sin}\left(\left[\begin{array}{cc}\pi & \frac{\pi }{2}\\ \frac{\pi }{2}& \frac{\pi }{3}\end{array}\right]\mathbit{X}\right)$, where $\mathbit{X}$ is a 2-by-1 symbolic matrix variable.

syms X [2 1] matrix
S = sin(hilb(2)*pi*X)
S =

Evaluate the expression with variable-precision arithmetic.

SVpa = vpa(S)
SVpa =

$\left(\begin{array}{c}\mathrm{sin}\left(3.1415926535897932384626433832795 {X}_{1}+1.5707963267948966192313216916398 {X}_{2}\right)\\ \mathrm{sin}\left(1.5707963267948966192313216916398 {X}_{1}+1.0471975511965977461542144610932 {X}_{2}\right)\end{array}\right)$

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, character vector, or matrix variable.

Number of significant digits, specified as a positive integer scalar. d must be greater than 1 and less than ${2}^{29}+1$.

Output Arguments

collapse all

Variable-precision output, returned as a symbolic number, vector, matrix, multidimensional array, expression, or function.

• For almost all input data types (such as sym, symmatrix, double, single, int64, and so on), vpa returns the output as data type sym.

• If the input is a symbolic function of type symfun, then vpa returns the output as data type symfun. For example, syms f(x); f(x) = pi*x; g = vpa(f) returns the output g as type symfun.

• If the input is an evaluated symbolic function of type sym, such as g = vpa(f(x)), then vpa returns the output as data type sym.

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.

• Variable-precision arithmetic is different from IEEE® Floating-Point Standard 754 in these ways:

• 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.

• Zeros 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

expand all