Fun with linspace and the colon operator in MATLAB

March 13th, 2009 | Categories: math software, matlab, programming | Tags:

Say you want a vector that starts at 0 and goes to 1 in steps of 0.1
There are two ways you might do this in MATLAB

x=0:0.1:1
y=linspace(0,1,11)

If you display either x or y then you will get

[0    0.1000    0.2000    0.3000    0.4000    0.5000    0.6000    0.7000    0.8000    0.9000    1.0000]

So it looks like we are in clover.  However if we do

x==y

we get

[1     1     1     0     1     1     1     1     1     1     1]

Which shows that the vectors x and y are not EXACTLY equal for all values (1 stands for true and 0 stands for false so one value is different).  We can see that the difference is extremely small by doing

x-y

1.0e-16 *
0         0         0    0.5551         0         0         0         0         0         0         0

This tiny difference is almost certainly caused by the fact that the colon operator and linspace use slightly different methods to calculate the vectors as pointed out in the newsgroup post where I discovered this little piece of trivia.  .  If floating point arithmetic was exact then it wouldn’t matter what algorithm you used to calculate a vector like this – the result would always be the same as you would expect.

However, floating point arithmetic isn’t exact and so things like the order of operations matters.  This sort of thing has been discussed many times by people considerably more erudite than me so I refer you to them for details.

What I was curious about was ‘How,exactly, does the colon operator calculate it’s values and how does this differ from linspace?’ Oh yes, I am a sucker for mathematical trivia.

If I didn’t have access to either of these methods in MATLAB then I would calculate our vector like this

n=0:10
a=n*0.1

But it turns out that this isn’t equal to either x or y so this isn’t how linspace or the colon operator works:

a==x (compare to colon operator)

1     1     1     1     1     1     0     0     1     1     1

a==y (compare to linspace)

1     1     1     0     1     1     0     0     1     1     1

Another way for calculating this vector that springs to mind is to start with 0 and repeatedly add 0.1 until you reach 1.  I normally would never do it like this due to the possibility of accumulating rounding errors on each addition but let’s take a look.

b=[zeros(1,11)];
for i=2:11
b(i)=b(i-1)+0.1;
end

As I’d expect, this isn’t how MATLAB does it either.

b==x (compare to colon operator)

1     1     1     1     1     1     1     1     0     0     0

b==y (compare to linspace)

1     1     1     0     1     1     1     1     0     0     0

My methods don’t agree with each other either (do a==b to see) but I was expecting that.

So, I am non the wiser.  How does linspace and the colon operator work? Thoughts and comments would be welcomed.

  1. March 13th, 2009 at 17:46
    Reply | Quote | #1

    Why not just see how matlab does it?

    >> edit linspace

    No code but at least some comments.
    >> edit colon

    /Björn

  2. Mike Croucher
    March 13th, 2009 at 18:25
    Reply | Quote | #2

    Hi

    Quite honestly – I didn’t know you could do that.
    Thanks for the information.

    Mike

  3. March 13th, 2009 at 21:26
    Reply | Quote | #3

    Hi

    Discovered it myself by mistake when trying to create a new function with the same name as a matlab function. Quite useful thou.

    /Björn

  4. HS
    March 13th, 2009 at 21:29
    Reply | Quote | #4

    Wow, I’m glad we have open-source software. Imagine the same question somehow intrigues you for a more difficult function or algorithm.

  5. hp
    March 13th, 2009 at 23:08
    Reply | Quote | #5

    you can edit most matlab file and change them.

  6. March 16th, 2009 at 19:12
    Reply | Quote | #6

    I expect the whole 80-bit/64-bit thing will crush any attempt to exactly replicate any particular matlab algorithm. Internally it will rightly feel justified in using Intel’s 80-bit format. but actual results will be rounded to 64-bit. Any particular piece of matlab code may or may not use 80-bit intermediates.

  7. Snorfalorpagus
    January 27th, 2010 at 17:11
    Reply | Quote | #7

    Also worth a look:

    http://www.mathworks.com/support/solutions/en/data/1-4FLI96/index.html?solution=1-4FLI96

    “For more detailed information on how the COLON operator works, refer to the attached function (COLONOP). This file mimics closely the behavior of the COLON operator.”

    http://www.mathworks.com/support/solutions/attachment.html?resid=1-4FLIOY&solution=1-4FLI96

  8. JackOLantern
    April 19th, 2013 at 10:02
    Reply | Quote | #8

    I have posted a question at

    http://stackoverflow.com/questions/16100850/accuracy-of-matlab-linspace-and-range-versus-kahan-summation-algorithm

    It seems that, by the Kahan summation algorithm, this problem is mitigated.