How to circumvent the extremely small output values? [duplicate] - matlab

This question already has an answer here:
Is there any way to increase 'realmax' in MATLAB?
(1 answer)
Closed 7 years ago.
For example in Matlab:
log(exp(-200)
-200
however
log(exp(-2000))
-inf
Naturally the input to the log function is passed as zero as exp(-2000) is insignificant and the log gives -inf. How can I fix this to receive -2000 instead?

If you have the Symbolic Math Toolbox, it's possible to do this with Variable Precision Arithmetic. Use the vpa function and place your mathematical expression as input into vpa wrapped in a string:
>> vpa('log(exp(-2000))')
ans =
-2000.0
However, this will be represented in symbolic format, so it may be prudent to convert back to a numerical value after you're done. Convert this result using double once you perform the calculation:
>> double(vpa('log(exp(-2000))'))
ans =
-2000

It is often possible to rewrite formulas in a way they do not exceed the range of floating point values. In your case, rewriting it would be trivially -2000. A more "real world" example can be found in this question where rewriting successfully avoided the problem.

Related

Why is my output value in exponential format 1.04e+05? [duplicate]

This question already has an answer here:
Why did MATLAB delete my decimals?
(1 answer)
Closed 4 years ago.
I am calculating the area of objects in my image using bwarea like so:
i=imread('Z:\Azhagu project work\MRI\input.jpg');
imshow(i);
bwarea(i)
This gives the following output:
ans = 1.0428e+05
Why is the area in an exponential format?
It's not in exponential output; it's in scientific notation.
ans = 1.0428e+05 == 104280
You can force MATLAB to show all decimals using format long or format longG. This is just a display quirk of MATLAB, internally your number is stored as a double anyway, so for further calculations this is of no concern.
This area value is not in exponential format. For your given image, area is represented in Floating-Point numbers format. Hence the value 1.0428e+05 is actually 104280.

63 is not equal to 2^(log(63)/log(2)) in Matlab [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Why is 24.0000 not equal to 24.0000 in MATLAB?
(6 answers)
Closed 6 years ago.
Because of the floating point error 2^(log(63)/log(2)) isn't equal to 63. Check the results below:
format long;
>> 2^(log(63)/log(2))
ans =
63.000000000000014
And unfortunatelly i can't use vpa on a logarithm according to the Matlab documents:
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.
So how can i solve this issue ? I have very big numbers like 2^200 and i get very big errors.
Edit: I'm not asking why it is happening. I'm asking how to make this work as 100% accurate so this isn't a duplicate.
The best solution so far:
Unfortunatelly the solution that is suggested by #Sardar_Usama isn't always working as intended. Check the results below:
>> sym(2^(log(2251799813685247)/log(2)))
ans =
2251799813685259
On the other hand
>> 2^(log(vpa(2251799813685247))/log(vpa(2)))
ans =
2.2517998136852470000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0*10^0*10^15
is much much more closer to 2251799813685247 = 2^51. It's error is around ~9.491*10^-494 which makes this the best solution so far but there is still some error.
If you cannot use round or vpa, there is a slower way of dealing this, if you have Symbolic Math Toolbox, by creating symbolic numbers . i.e.
a = sym(2^(log(63)/log(2)))
This will give you sym class 63 which you can later convert to double using:
double(a)
This is what you'll get:
>> format long
>> a = sym(2^(log(63)/log(2)))
a =
63
>> double(a)
ans =
63

Floating Point Number Overflow [duplicate]

This question already has an answer here:
How to deal with overflow and underflow?
(1 answer)
Closed 7 years ago.
I have to create a function where I need to square values. I am told that even if the initial value is not too big or is not too small, the value squared might still overflow (returns inf) or underflow (returns 0), and I need to figure out how to prevent that.
My problem is I do not even understand what numbers can cause an overflow when squared when the number itself is not too large.
I thought it might be for the not too small numbers, e.g. 1/3 with repeating decimal numbers, but MATLAB just turns that into 0.3333.
Can someone give me an example of such a number or explain what kind of numbers would cause this?
For underflow, let's consider Planck's constant: 6.626070040e-34
sqrt(6.626070040e-34)
ans =
2.5741e-17
Well, that's apparently not small enough, let's go smaller:
sqrt(6.626070040e-340)
ans =
0
There's your underflow.
Overflow can be seen the same way, just use big numbers:
sqrt(6.626070040e34)
ans =
2.5741e+17
sqrt(6.626070040e340)
ans =
Inf
Underflow means the numbers are too small for MATLAB to handle, overflow means they are too big for MATLAB to handle.
Thanks to #obchardon here are the numbers on my MATLAB R2012a 64bits system:
realmax('double') %//largest allowed double
ans =
1.7977e+308
realmin('double') %//smallest allowed double
ans =
2.2251e-308
Now that we know what the largest possible value is that MATLAB can handle, let's try going below that and square it:
(realmax('double')-10).^2
ans =
Inf
so the number we tried to square here (realmax('double')-10) is allowable by MATLAB, but not squarable.

exponential function with large argument in matlab [duplicate]

This question already has answers here:
How to compute an exponent in matlab without getting inf?
(3 answers)
Closed 7 years ago.
I've got one problem for a longer time and I'd be really grateful if you could help me somehow...
I have a code in MATLAB (version R2012a) where I compute some exponential functions using MATLAB's fuction exp. This means that I have something like this:
y = exp(x);
However, when this "x" is larger than a certain number, the result ("y") is infinity; when "x" is smaller than a certain number, the result is 0. As said on the MathWorks' website:
Numerical exceptions may happen, when the absolute value of the real
part of a floating-point argument x is large. If ℜ(x) < -7.4*10^8,
then exp(x) may return the truncated result 0.0 (protection against
underflow). If ℜ(x) > 7.4*10^8, then exp(x) may return the
floating-point equivalent RD_INF of infinity.
My problem is quite obvious - my "x" are pretty large so I receive infinities and zeros instead of results I need. My question is - how do I get the real results? Thanks in advance for help!
Use vpa with a string input:
>> exp(1000)
ans =
Inf
>> vpa('exp(1000)')
ans =
1.9700711140170469938888793522433*10^434
Note the result of vpa is of class sym.
A variable in any language is stored in a certain amount of bytes in the computer's memory. The more bytes used to hold a variable type, the more precise of a result that variable can hold. If you are using integers, the biggest type uses 64 bytes and is uint64. This is an unsigned integer (meaning it can only be positive) that can range from 0 to 18,446,744,073,709, 551,615. If you need decimals, try using vpa.

why I cannot get just a number [duplicate]

This question already has answers here:
Convert output from symbolic math (sym) to float
(2 answers)
Closed 8 years ago.
I did following:
clc
clear all
I0=1.2e12;
FWHM=10e-12;
c=FWHM./2.35482;
t=0:1e-12:50e-12;
syms t
int(I0.*exp(-1.*(t-5e-12).^2./(2.*c.^2)),t,0,40e-12)
but it does not give me a simple number (just a number)
The reason why matlab does not automatically give you a number is that precision could be lost.
Suppose you have a symbolic variable with value 1/3. That has infinite accuracy at this point. Yet if you evaluate it, you would lose this precision, so that is why it is not evaluated directly.
If you want to evaluate it, you could do that of course. Try doc double,doc vpa, doc eval or doc subs. I think the first one is what you need.