How do I make linspace work for small numbers? - matlab

I am trying to use linspace in Matlab for small numbers, e.g. from 0.00003 to 0.1.
However, if I do this, the first number/bin is not 0.00003, but 0, which does not give me an equal distribution:
linspace(0.00003,0.1,10)
ans =
0.0000 0.0111 0.0222 0.0334 0.0445 0.0556 0.0667 0.0778 0.0889 0.1000
I realized that if I start with 0.0003 or larger then it works, but how can I make it work for smaller numbers?

This is purely due to the way that the MATLAB command window is displaying your data.
The default way that numbers are displayed is the short format which the documentation states is:
Short, fixed-decimal format with 4 digits after the decimal point
Your first data point doesn't have a non-zero digit until the 5th digit after the decimal point so it simply shows up as 0.0000.
Try changing the display format to something that will show more significant digits. You can do this using format.
format long g
Also, in the future, if you actually want to check that something is behaving as you expect, do an explicit check by value not just by trusting what shows up in the command window.
limit = 0.000003
data = linsapce(limit, 0.1, 10);
% Check that the first datapoint is "equal" to what you expect
assert(abs(data(1) - limit) < eps)

Related

Why did MATLAB delete my decimals?

Let's say I create some number A, of the order 10^4:
A = 81472.368639;
disp(A)
8.1472e+04
That wasn't what I wanted. Where are my decimals? There should be six decimals more. Checking the variable editor shows me this:
Again, I lost my decimals. How do I keep these for further calculations?
Scientific notation, or why you didn't lose any decimals
You didn't lose any decimals, this is just MATLAB's way of displaying large numbers. MATLAB rounds the display of numbers, both in the command window and in the variable editor, to one digit before the dot and four after that, using scientific notation. Scientific notation is the Xe+y notation, where X is some number, and y an integer. This means X times 10 to the power of y, which can be visualised as "shift the dot to the right for y places" (or to the left if y is negative).
Force MATLAB to show you all your decimals
Now that we know what MATLAB does, can we force it to show us our number? Of course, there're several options for that, the easiest is setting a longer format. The most used for displaying long numbers are format long and format longG, whose difference is apparent when we use them:
format long
A
A =
8.1472368639e+04
format longG
A
A =
81472.368639
format long displays all decimals (up to 16 total) using scientific notation, format longG tries to display numbers without scientific notation but with most available decimals, again: as many as there are or up to 16 digits, both before and after the dot, in total.
A more fancy solution is using disp(sprintf()) or fprintf if you want an exact number of decimals before the dot, after the dot, or both:
fprintf('A = %5.3f\n',A) % \n is just to force a line break
A = 81472.369
disp(sprintf('A = %5.2f\n',A))
A = 81472.37
Finally, remember the variable editor? How do we get that to show our variable completely? Simple: click on the cell containing the number:
So, in short: we didn't lose any decimals along the way, MATLAB still stores them internally, it just displays less decimals by default.
Other uses of format
format has another nice property in that you can set format compact, which gets rid of all the additional empty lines which MATLAB normally adds in the command window:
format compact
format long
A
A =
8.147236863931789e+04
format longG
A
A =
81472.3686393179
which in my opinion is very handy when you don't want to make your command window very big, but don't want to scroll a lot either.
format shortG and format longG are useful when your array has very different numbers in them:
b = 10.^(-3:3);
A.*b
ans =
1.0e+07 *
0.0000 0.0001 0.0008 0.0081 0.0815 0.8147 8.1472
format longG
A.*b
ans =
Columns 1 through 3
81.472368639 814.72368639 8147.2368639
Columns 4 through 6
81472.368639 814723.68639 8147236.8639
Column 7
81472368.639
format shortG
A.*b
ans =
81.472 814.72 8147.2 81472 8.1472e+05 8.1472e+06 8.1472e+07
i.e. they work like long and short on single numbers, but chooses the most convenient display format for each of the numbers.
There's a few more exotic options, like shortE, shortEng, hex etc, but those you can find well documented in The MathWork's own documentation on format.

Matlab enforce variable accuracy

I have two double arrays that are of equal size but one always has the following format:
A1 = 0.0756 0.0368 0.0124 0.0024 0.0002 0.0000 0.0000
while the other one is:
A2 = 0.0797 0.0368 0.0120 0.0024 0.0004 0 0
I want to enforce the last two elements to be of the same accuracy, that is be 0.0000 instead of 0. Trying the naïve approach of A2(7) = 0.0000 does not work, although A2(7) = A1(7) does the trick.
How can I archive this a bit more cleverly?
Careful! I think you will find the A1(7) == 0 returns false.
What exactly do you mean by the same accuracy? Internally matlab uses the same precision for every element of both of your arrays (they're all doubles). It is just displaying them differently.
Try the following commands:
A1(7);
format long g
A1(7);
and I think you'll find that in fact A1(7) isn't 0 and furthermore is also accurate to far more than the 4 decimal points you are seeing.
So the question is, do you actually want to round off to 4 decimal places? Or do you just want to display up to 4 decimal places? I image you want the latter, so have a look at sprintf
The numbers actually already have the desired precision. If you want you can print them with any amount of digits you like (Though typically only about the first fourteen will be significant).
For this you can use the various print commands, however if you want to change the default way numbers are displayed, your simple options are quite limited.
Check help format for the things you can choose from.
If you always want to show a minmum number of decimals, I believe your only choice is:
format shorteng

get vector which's mean is zero from arbitrary vector

as i know to get zero mean vector from given vector,we should substract mean of given vector from each memeber of this vector.for example let us see following example
r=rand(1,6)
we get
0.8687 0.0844 0.3998 0.2599 0.8001 0.4314
let us create another vector s by following operation
s=r-mean(r(:));
after this we get
0.3947 -0.3896 -0.0743 -0.2142 0.3260 -0.0426
if we calculate mean of s by following formula
mean(s)
we get
ans =
-5.5511e-017
actually as i have checked this number is very small
-5.5511*exp(-017)
ans =
-2.2981e-007
so we should think that our vector has mean zero?so it means that that small deviation from 0 is because of round off error?for exmaple when we are creating white noise or such kind off random uncorrelated sequence of data,actually it is already supposed that even for such small data far from 0,it has zero mean and it is supposed in this case that for example for this case
-5.5511e-017 =0 ?
approximately of course
e-017 means 10 to the power of -17 (10^-17) but still the number is very small and hypothetically it is 0. And if you type
format long;
you will see the real precision used by Matlab
Actually you can refer to the eps command. Although matlab uses double that can encode numbers down to 2.2251e-308 the precission is determined size of the number.
Use it in the format eps(number) - it tell you the how large is the influence of the least significant bit.
on my machine eg. eps(0.3) returns 5.5511e-17 - exactly the number you report.

Matlab gives wrong answer on mod(), isequal(), floor() function with a vector parameter

I am using matlab to solve a mixed integer programming, after I obtain a solution from linprog, I want to evaluate whether they are all integers(x is n dimensions), but I cannot figure out a way to do this.
All the functions, such as mod(x,1) == 0, isequal(x,floor(x)) will give a wrong anwser.
More strange is, if you manually input a vector with the same parameter, it will turn out to be right.
The result is shown: (all the x here is obtained from the result of linprog). Anyone can help with this or bring out some other useful way to evaluate this?
K>> x
x =
7.0000
1.0000
K>> mod(x,1)
ans =
0.0000
1.0000
K>> x
x =
6.0000
3.0000
K>> isequal(x,floor(x))
ans =
0
What seems to be an integral 1 coming from linprog, actually is a floating point number very close to 1, but not equal to it. It's just that you (by default) cannot tell the difference by outputting the number in MATLAB. See this Question about comparing floating point values. Also, see the MATLAB manual page about display format of numbers.
By default, MATLAB displays numbers using format short:
format sets the display of floating-point numeric values to the default display format, which is the short fixed decimal format. This format displays 5-digit scaled, fixed-point values.
So, 1 – 1e–10 would be displayed as 1 even though it is not equal to 1. Likewise, mod(1 – 1e–10, 1) would be displayed as 1, even though it really is 1 – 1e–10.
If you manually set x to its displayed representation, all the less significant digits are truncated, “strangely” giving you the expected results.
Check x after typing the command format long.

Issue in viewing double values

I am having an issue with viewing double data in matlab console. Actually, I am importing a matrix from my data file. The value of a particular row and column was 1.543 but in the console when I use disp(x) where x is the matrix imported, it is showing as 1.0e+03 * 0.0002. However, when I try to access that particular element in the matrix using disp(x(25,25)) where 25 and 25 are the row and column numbers it is showing to be 1.543. So I am confused. Any clarifications. It is just that when I print the whole matrix it is showing as 1.0e+03 * 0.0002.
The following command should fix it. It is only a display issue, the precision of the actual values in the matrix are not affected:
format shortG
That happens due to high dynamic range of your data.
Try for example :
x = [10^-10 10^10];
disp(x);
The result is:
1.0e+010 *
0.0000 1.0000
It looks like the first value is zero, but it isn't. It is almost zero compared to the second one. That is not surprising. Try to add to the big value the small one, and subtract, and you get zero. That is due to floating point arithmetic.The following expression is true
isequal( (x(1)+x(2)) - x(2) , 0)
What can be done?
1) A really high dynamic range can cause troubles in any kind of computations. Try to understand where it came from, and solve the problem in a broader context.
2). You can try to set
format long
It can improve the situation visually for some of the cases.