Skip to Main Content Skip to Search
File Exchange
MATLAB Newsgroup
Link Exchange
  Blogs  
 Contest 
MathWorks.com

Loren on the Art of MATLAB

October 25th, 2006

Cute Tricks in MATLAB Adapted from Other Languages

I recently saw Steve Baker's web site while searching for something. It contains some cute (Steve's word) programming tricks and I thought I would show how to do a couple of these in MATLAB.

Contents

Power of Two Test

Here's the C code:

     b = ((n&(n-1))==0) ;

and now the M code:

n = 1:8
ispow2 = bitand(n,n-1) == 0
n =
     1     2     3     4     5     6     7     8
ispow2 =
     1     1     0     1     0     0     0     1

Swap Two Integer Values

C code to swap integers x and y x = x ^ y ; y = x ^ y ; x = x ^ y ;

x = 3
y = 17
x = bitxor(x,y)
y = bitxor(x,y)
x = bitxor(x,y)
x =
     3
y =
    17
x =
    18
y =
     3
x =
    17

Of course, I showed how to do this more easily a while ago using an anonymous function:

swap=@(varargin)varargin{nargin:-1:1};
x = 3
y = 17
[x,y] = swap(x,y)
x =
     3
y =
    17
x =
    17
y =
     3

Force All Non-zeros to 1

The C code:

              b = !!a ;

and the MATLAB code:

a = [0 1 3 0 5 7 9 0 -3 0 0]
b = +(a~=0)  % use leading + to make result double instead of logical.
a =
     0     1     3     0     5     7     9     0    -3     0     0
b =
     0     1     1     0     1     1     1     0     1     0     0

What Byte Order is My Computer?

The C code:

     int i = 1 ;
     little_endian = *((char *) &i ) ;

and the MATLAB code:

a = uint16(1);
b = typecast(a,'uint8')
little = [1 0];  % big = [0 1];
islittle = isequal(b,little)
b =
    1    0
islittle =
     1

or

[omit, omit, endian] = computer
omit =
  2.1475e+009
omit =
  2.1475e+009
endian =
L

Set Different Bits

Set the least significant bit to 0. Here's the C code.

    n&(n-1)

and the M code:

n = uint8(0:7)
lb1 = bitset(n,1,0)
n =
    0    1    2    3    4    5    6    7
lb1 =
    0    0    2    2    4    4    6    6

Other Tricks?

Share your MATLAB tricks with me.

Acknowledgment

Steve Eddins, famous for many things, including his blog on image processing, just updated one of our blog publishing tools, allowing you to see the code behind most of our posts with the push of a mouse button. Pretty cool, huh! Be sure to read his recent blog article about the default MATLAB image.


Get the MATLAB code

Published with MATLAB® 7.3

27 Responses to “Cute Tricks in MATLAB Adapted from Other Languages”

  1. Siamak replied on :

    I think we have talked about the tricks I used to use before (like using “if 2==a” instead of “if a==2″) I don’t use it anymore since it confuses other programmers and causes inconsistency but it is a little faster, and I also try to avoid division calculations in my code and use multiplication by the inverse of the number instead, I think I have described them in your “What Are You Really Measuring?” post

    By the way, this “Get MATLAB code” is really cool but I think it has a bug and needs improvement,

    in the browser it looks okay (I use Firefox) but I use your RSS feed most of the times to read Mathwork’s blogs and the problem is, the javascript behind the code is also shown in the RSS channel and makes the post ugly

  2. Loren replied on :

    For users with the same grabcode issue as Siamak about the RSS reader: there are readers without this issue, for example, Thunderbird or Sage.

    –Loren

  3. Petr Pošík replied on :

    Hi Loren.

    Swapping two integer values can be made through the deal function

    [x,y] = deal(y,x);

    But the deal function is probably slower.

    Petr

  4. Kevin Hung replied on :

    I think there is a typo under section “Set Different Bits”, the give C code actually sets the least significant bit to 0. This is correct in Steve’s website.

  5. Loren replied on :

    Kevin-

    Thanks! I fixed the typo.

    –Loren

  6. Richard Hindmarsh replied on :

    Force non-zeros to 1

    On my AMD XP system at least the “C”-like code is faster. Does it have a worse memory overhead?

    >> a = full(sprand(1000,1000,0.1));
    >> tic;+(a~=0);toc
    Elapsed time is 0.052537 seconds.
    >> tic;~~a;toc
    Elapsed time is 0.016447 seconds.

  7. Loren replied on :

    Richard-

    If I put your statements in a function, I get different results and they are much closer on my laptop. The size calculation may be too small to be completely meaningful.

    Elapsed time is 0.019397 seconds.
    Elapsed time is 0.012486 seconds.

    By the way, I wasn’t making any speed claims in this blog, just noting different ways one might compute certain logical and bitwise functions in MATLAB vs. C.

    –Loren

  8. Loren replied on :

    Richard-

    Actually, your two expressions aren’t the same. The first converts to double and the second stays logical (less memory allocation). I think the C code was trying to keep the datatype the same as well.

    –Loren

  9. Jeff replied on :

    Loren,

    Great topic. Interesting stuff to this ‘non-programmer’.

    May still be a problem in the “Set Different Bits” section tho. Typo in comment is fixed, but I think the MATLAB code shown is still setting the LSB to 1.

    Should be “lb1 = bitset(n,1,0)”?

    Thanks,
    Jeff

  10. Loren replied on :

    Jeff-

    Right you are again. Sorry I was so sloppy. It should be fixed now.

    –Loren

  11. Oliver A. Chapman, PE replied on :

    A 40+ year programmer that I work with frequently says, “If it is clever, likely you shouldn’t use it.” Of course, this overstates it to make the point. Which is that the primary objective of code is to demonstrate clearly that it is doing the proper things. Dykstra advocated this approach some 40 years ago. We’ve found that clever coding is frequently less clear than other techniques.

    When my co-worker & I reviewed this column, we had trouble understanding how these tricks were useful. e.g., we couldn’t easily see what function they were doing, or how it was useful.

    However, I did learn something very useful and that was how to convert a logical MatLab variable to a number by preceding it with the “+”. This leads to the question, “Where is the MatLab function that does this? Something like, “logic2num”

  12. Loren replied on :

    Oliver-

    If you want to convert it to double, just say double(x). Using the “constructor” is generally the way to do the conversion as well in MATLAB.

    –Loren

  13. Doug Schwarz replied on :

    I agree with Oliver that these clever tricks are interesting and fun, but unless you well document their use they can be confusing.

    By the way, Oliver, the function that is run when you do +x is uplus (as in uplus(x)), but I agree with Loren that you should use the constructor and make the conversion explicit.

  14. David Mackenzie replied on :

    Loren,

    one of the main reasons for writing such apparently obscure code in languages such as C is that it compiles to only one or two machine instructions on most processors and is therefore very fast - however, this is not at all the case with MATLAB’s bit… functions, which I perceive as painfully slow in comparison, unfortunately.

    I did note your comment above that you’re not making any speed claims here - this isn’t meant in any way as a criticism of your blog, which I very much enjoy reading, thank you!

    David

  15. Mohammad Reza replied on :

    How about a leap year test?

    isleap = @(x) isodd(sum(0 == mod(x, [4 100 400])));

    where

    isodd = @(x) mod(x,2);
    and x has to be scalar due to dimension restriction in mod().

    This comes from J, an array oriented language. In native J it looks like:

    isleap =. 0: ~:/ .= 4 100 400 |/ ]

    Here the input need not be scalar.

    The interesting trick in J is when trying to determine if the result of mod() contains and even or odd number of zeros. It does this by “inserting” a not-equal in the output of the comparision test.

    Inserting a function is a generalisation of summation where +/ 1 2 3 is the same as 1 + 2 + 3 ie insert a ‘+’ between the elements of the array. In our case we have ~:/ which says insert a “not equal” between the elements of the array. So we have one of the following cases:

    1 ~: 1 ~: 1 => 1
    0 ~: 1 ~: 1 => 0
    1 ~: 0 ~: 1 => 0
    1 ~: 1 ~: 0 => 0
    1 ~: 0 ~: 0 => 1
    0 ~: 1 ~: 0 => 1
    0 ~: 0 ~: 1 => 1
    0 ~: 0 ~: 0 => 0

    where ~: is the same as ~= in matlab

    /m

  16. Mohammad Reza replied on :

    I should add that expressions in J are evaluated from right to left. Apart from the parans there are no operator precedence rules. So

    1 ~: 1 ~: 1 is the same as (1 ~: (1 ~: 1))

    /m

  17. venkateswarlu replied on :

    sir,
    the codes mentioned above are very nice.i need matlab code for comparision of an image with another image that has already been stored in database.

  18. David replied on :

    Please make a shell extension and/or browser plug-in to right click and execute MATLAB code. Thank you. Feel free to contact me by email if needed.

  19. Loren replied on :

    David-

    Here’s what we have in MATLAB now:

    http://www.mathworks.com/access/helpdesk/help/techdoc/learn_matlab/f1-23058.html

    the ability to evaluate selected code in the MATLAB supplied browser. See also
    this page and look for “Evaluate a Selection”

    I’ll pass along your suggestion.

    –Loren

  20. David replied on :

    Thanks. More to the point I meant evaluating a selection from a web page. Unsure of how you would handle this if multiple instances of MATLAB were running, but I am sure you guys will think of something. Cheers.

  21. David replied on :

    One More Comment before I disappear…

    >>data’

    ans =

    [1×74 char]
    [1×82 char]
    [1×80 char]
    [1×81 char]

    it would be nice if when displaying ans, the command window would have the index next to the data (e.g. 1,2,3,4 to the left of 1×74, 1×82,etc…). Thanks.

  22. marko replied on :

    Hello!

    I have another question, sorry if this is not a right blog.
    I have to convert uint8 iamges to uint16 images by setting upper byte to 0. how can this be done? Is there any function, which opeates on whole image matrix or i have to convert each number/pixel value?

    Thank…

  23. Steve Eddins replied on :

    Marko—Use the uint16 function.

  24. marko replied on :

    but this function really does the upper (most important byte) equal to 0? i found that for example you can do this with “typecast” function, which combine 2 uint8 values to one uint16 and you have control on byte value and byte order…

  25. Steve Eddins replied on :

    Marko—uint16 does the operation you describe. typecast does not.

  26. marko replied on :

    OK! very nice! Thank you for you help…but i have another questions, if you dont mind: how can i matlab open and save raw image files (iamge.raw)?

  27. Loren replied on :

    Marko-

    Perhaps you could take this discussion off-line or with technical support as it is not on-topic for this blog article. Thank you.

    -Loren

Leave a Reply


Loren Shure works on design of the MATLAB language at The MathWorks. She writes here about once a week on MATLAB programming and related topics.

  • J.B. Brown: Ah, and I am at fault for simply testing collinearity with the origin in the example above.
  • J.B. Brown: Indeed, > collinear( [0 3],[0 8],[0 -1e21+2e-15] ) ans = 1 > collinear( [0 3],[0 8],[0 -1e22+2e-15]...
  • OkinawaDolphin: Loren, thank you for telling me where to download timeit. Here are the two functions I just tested...
  • Loren: JB- It looks to me like Ilya’s solution and therefore yours are equivalent to the determinant. As Tim...
  • Loren: OkinawaDolphin, timeit can be downloaded from the File Exchange. Steve Eddins is the author. It does not ship...
  • OkinawaDolphin: It seems that neither R2007a nor R2007b have the function timeit, but I investigated computation time...
  • J.B. Brown: It would appear to me that Ilya Rozenfeld’s solution would be the cleanest. Just to help those who...
  • Loren: Markus- Congratulations on winning! And a nice illustration of how the size matters. Small enough, and the...
  • Markus: Hi Loren, which version is fastest also depends very much on the matrix dimensions. Look at my test function:...
  • Duncan: OkinawaDolphin, Regarding why your third example is slower than your second example, the result is in fact...

These postings are the author's and don't necessarily represent the opinions of The MathWorks.

Related Topics