# vpa(4503599627370491.5)

9 views (last 30 days)

Show older comments

vpa(4503599627370491.5) produces 4503599627370496.0 in 2017b. Why?

Further, sym(4503599627370491.5)-sym(4503599627370496) produces 0.

##### 0 Comments

### Answers (4)

Walter Roberson
on 12 Feb 2018

sym and vpa are normal functions. Their arguments are evaluated with the normal MATLAB rules before the function is called. Double precision losses information on a number that large before it gets passed on.

You should enclose large numbers in quotes for use with vpa or syms.

Note: the use of sym on character vectors representing numeric constants will continue to be supported, as will sym on a character string representing a simple variable name. The functionality being discontinued within a small number of releases is using sym() on a character string representing an expression. sym() is defined as treating the character strings as MuPad expressions and the replacement functionality str2sym will instead treat it as MATLAB syntax.

##### 0 Comments

Jon Dattorro
on 7 Sep 2023

##### 11 Comments

Walter Roberson
on 25 Sep 2023

vpa() will return a symfun if the parameter to vpa() evaluates to a symfun .

syms x

f(x) = x/sym(pi)

g1 = vpa(f)

g2 = vpa(3*x + tan(x)^2 + f)

g3 = vpa(f^3)

g4 = vpa( symfun(gamma(x)^2, x) )

g5 = vpa(f(x)) %f(x) is not a symfun

whos

vpa() will not return a symfun in any case where the expression does not evaluate to a symfun. In the example of f(x): invoking a symfun() with a definite parameter evaluates the function on the given parameter, returning a symbolic expression.

Pavel Holoborodko
on 25 Sep 2023

Edited: Pavel Holoborodko
on 25 Sep 2023

@"Expecting vpa() to return anything other than sym (or sometimes, symfun) is a substantial misunderstanding of the Symbolic Toolbox...."

I see, the "vpa" is actually a factory function, generating the instances of "sym" class. I stand corrected, "sym.diff" is the full name of the function.

However, these technical details of SMT implementation have nothing to do with the point we are discussing. We discuss the semantics of the functions in SMT. In other words, what the SMT functions do (or should do) with the input arguments. The type they return is just a technicality in this context.

The SMT does much more than pure symbolic operations. Many functions in SMT apply numerical algorithms (using extended precision) to compute the output results. For example, take a look on EIG:

% LAMBDA = EIG(VPA(A)) and [V,D] = EIG(VPA(A)) compute numeric eigenvalues

% and eigenvectors using variable precision arithmetic. If A does not

% have a full set of eigenvectors, the columns of V will not be linearly

% independent.

Same for SVD, or other cases where result cannot be computed analytically or arbitrary-precision plays an important role.

(Of course the functions still return result of type "sym", but the result itself was computed numerically. I hope this distinction is clear.)

This is exactly the case with "diff". Extended precision is important for computing numerical derivatives/differences accurately, since it is a highly ill-conditioned problem (e.g. same as eigenvalues). Therefore it is quite natural to expect the "sym.diff" to have this functionality.

Besides, the original meaning of "diff" stands the same since the MATLAB inception - computing differences and numeric derivatives. It is not clear why SMT developers decided to change its semantics in SMT. They could've just introduced the new function for symbolic derivatives, as @Paul said. Ambiguity would be avoided.

Here is simple example for illustration:

>> A = vpa(rand(3)); % Store numeric matrix as 'sym'

>> ev = eig(A) % Computes e-vals NUMERICALLY using extended precision (see sym.eig)

ev =

1.752670342542888271728211766393

0.8398632587280311835223044391663

-0.18794383321803341008176836388774

>> class(ev) % Result stored as 'sym', but it is inherently numeric

ans =

'sym'

Similarly, I expect the "sym.diff" to provide the analogous functionality of built-in "diff" and to work as "sym.eig" above - compute result numerically using extended precision. But instead we see:

>> d = diff(A)

d =

[0, 0, 0]

[0, 0, 0]

[0, 0, 0]

##### 11 Comments

Walter Roberson
on 29 Sep 2023

Pavel Holoborodko
on 3 Oct 2023

Edited: Pavel Holoborodko
on 5 Oct 2023

This covers only the simplest case when the user passes the typename argument explicitly (e.g. zeros(...,'mp')).

However, in most of the cases, existing/legacy code relies on default form, without the typename argument.

That is why our users requested to provide a special mode in which the array-creation functions generate extended-precision arrays by default (e.g. when no typename is specified, or it refers to standard floating-point types - 'double' or 'single').

This is useful when legacy code of considerable volume needs to be converted to extended precision:

>> mp.OverrideDoubleBasicArrays(true); % Basic arrays are created as 'mp' by default

>> A = zeros(3);

>> whos A

Name Size Bytes Class Attributes

A 3x3 272 mp

>> % Run legacy code with zeros(...), eye(...), etc.

>> % ...

>> mp.OverrideDoubleBasicArrays(false); % Return to default behavior

That is why our toolbox has to supersede the default functions and call them only when applicable (using 'builtin' calls). This approach works well, with the exception of slow 'builtin' calls.

***

Another interesting case is when the functions are called without arguments at all, e.g. zeros, eye, etc. This case is treated differently by MATLAB - it just returns 0 or 1, without even calling the global/built-in functions. No OOP involved, this is just hardcoded in MATLAB. Meaning these cases are impossible to overload for custom class types at all. Even by superseding the built-in functions.

### See Also

### Categories

### Products

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!