symbolic, vpa and double decision
19 views (last 30 days)
Show older comments
I am reading the link below:
I wrote the code below:
a=sym(pi);
b=vpa(pi, 3);
c=double(pi);
whos
It looks like all of them uses 8 bytes, which means 64 digits. My questions are:
1. why is c using 64 digits even though it is a double precision data type?
2. Since they all use the same amount of digits, why does the table say symbolic uses "Greatest" memory and double uses "least" memory?
Thank you,
1 Comment
Stephen23
on 12 Aug 2017
Edited: Stephen23
on 12 Aug 2017
>> a=sym(pi); b=vpa(pi, 3); c=double(pi); whos
Name Size Bytes Class Attributes
a 1x1 60 sym
b 1x1 60 sym
c 1x1 8 double
"It looks like all of them uses 8 bytes, which means 64 digits."
Eight bytes means sixty-four bits. "eight bytes" tells nothing about how many digits (until the encoding is specified).
Answers (1)
Walter Roberson
on 12 Aug 2017
Double precision uses 64 bits, in IEEE 754 format; one bits is used for a sign bit, 11 bits are used for the exponent, and 52 bits are used for the mantissa. However, because of the "hidden bit" way of representing the exponent, for all "normalized" numbers (which is most of them) there is an implicit 53rd bit before the 52 bits that is always 1 for normalized numbers. This gives an effective precision of 53 bits.
All sym variables are internally represented as handles to an object; the object has a small number of properties, none of which is the actual "value" of the symbol. Instead there is a property which is the name of a variable that lives inside the MuPAD symbolic engine. All symbolic computation is done by looking up the MuPAD variable name and passing that name to the symbolic engine; at the MATLAB level, MATLAB does not have any clue as to what the value of the variable is, so MATLAB does not know how much memory the MuPAD engine is using to represent the variable. There isn't really any way to ask MuPAD how much space a variable is taking either (it gets complicated to compute, as sub-expressions can share storage in MuPAD.)
The size, 8 bytes, that whos reports for a sym is the size of the handle to the sym object.
This is the same size behaviour you would see for
fig = gcf;
whos fig
Name Size Bytes Class Attributes
fig 1x1 8 matlab.ui.Figure
Figures do not really take up as little as 8 bytes, but the handle to the object takes up 8 bytes.
3 Comments
Walter Roberson
on 13 Aug 2017
"Yes, you have to be careful with round-off with double precision; it is not an exact calculation".
16 digits of precision is the decimal approximation to 53 bits of precision. 1 + 2^(-53) has the same representation as 1 does; 1 + 2^(-52) has a different representation than 1 does. The leading bit for the 1, and then 52 usable bits afterwards, gives 53 total bits precision. 2^(-53) is exactly 1.1102230246251565404236316680908203125e-16 which is close enough to 1E-16 that people just say 10^-16 . But you could also make an argument for talking about 2E-16 or 2.220446049250313080847263336181640625e-16 which is 2^(-52), the smallest value that can be added to 1 to get a different value than 1.
In any case, do not make the mistake of thinking that 1 and 1+1E-16 are different representations: it is not literally 16 decimal places, only approximately that no matter which way you are looking at it. And people get confused about the differences between "half of 16 decimal places", or "twice 16 decimal places" or "two times 16 decimal places", or even "half as good as you would get if you had 16 decimal places"...
Walter Roberson
on 13 Aug 2017
"It seems to me that vpa is still a symbolic arithmetic."
Pretty much everything that table says about speed and memory use is only an approximation to the truth. It is also an approximation to the truth to write about variable precision arithmetic as if it were something different than symbolic arithmetic: it is not.
According to one of my support cases, what is referred to here as "variable precision arithmetic" is represented as a pair of integers in base 2^31. Using 32 bit chunks would probably have been easier, so I must presume there was good technical reason for going with 31 bit chunks; for example one of the known indefinite-precision representation schemes sets the top bit in every chunk except the last to indicate that the number is "continued" in a further chunk. Or perhaps the library finds it convenient to copy the sign bit to every chunk.
The representation of floating point values as a pair of integers would imply that the representation is effectively the mantissa as a decimal integer numerator, together with a base 10 integer denominator, in which case the operations would take place the same way as for rationals. The difference in operation would be in truncating the calculation at appropriate points, and in not converting to lowest terms.
My tests suggest that for digits(D), that the error for
sym(1)-sym('.000001')*1000000
is 10^(-D) / 2^26, except that the error is chunked into binary; for example,
>> digits(10032); log2(sym(1)-sym('.000001')*1000000)
ans =
-33352.0
>> vpa(-(10032*log2(sym(10))+26))
ans =
-33351.58264 [...]
10014 digits was the previous digits value that shows a non-zero error, namely 2^-33292
At this time, I do not know how the 2^26 factor arises.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!