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

Loren on the Art of MATLAB

February 16th, 2007

Reordering Arrays

There are some cases, particularly simulations, in which we need to choose a few items from a finite list. A friend mentioned to me that he was doing a Monte Carlo simulation for a card game and wanted to deal out some card hands. It was easier for him to look at the hands if the cards were ordered so they were listed with the hands with the smallest high values were first on the list. As you can imagine, there are lots of ways to do this in MATLAB, and some take longer than others. Also, there are some variants on how to order the hands based on the lowest or intermediate cards, once the highest ones are duly sorted. Why does this matter? For my friend, the right ordering reduced his simulation times from 40 hours (so many hands!) to 15 hours, a 60% savings in time.

Contents

Deal Some Cards

Let's find out all the card combinations taking 3 cards at a time and look at the first few.

hands3 = nchoosek(1:52,3);
hands3(1:10,:)
ans =
     1     2     3
     1     2     4
     1     2     5
     1     2     6
     1     2     7
     1     2     8
     1     2     9
     1     2    10
     1     2    11
     1     2    12

Reorder Cards by Lowest High Value

Let's first try 3 different ways to reorder the cards, using

handsr = rot90(hands3,2);
handsr(1:8,:)
ans =
    52    51    50
    52    51    49
    52    50    49
    51    50    49
    52    51    48
    52    50    48
    51    50    48
    52    49    48

These values start with the high ones, so let's transform our deck.

hands3t = 53-hands3;
tic
handsr = rot90(hands3t,2);
toc
handsr(1:8,:)
Elapsed time is 0.000998 seconds.
ans =
     1     2     3
     1     2     4
     1     3     4
     2     3     4
     1     2     5
     1     3     5
     2     3     5
     1     4     5
tic
handsff = flipud(fliplr(hands3t));
toc
handsff(1:8,:)
Elapsed time is 0.002005 seconds.
ans =
     1     2     3
     1     2     4
     1     3     4
     2     3     4
     1     2     5
     1     3     5
     2     3     5
     1     4     5
tic
handsind = hands3t(end:-1:1,end:-1:1);
toc
handsind(1:8,:)
Elapsed time is 0.000973 seconds.
ans =
     1     2     3
     1     2     4
     1     3     4
     2     3     4
     1     2     5
     1     3     5
     2     3     5
     1     4     5
sameOrder = isequal(handsr, handsff, handsind)
sameOrder =
     1

Another Ordering

You can use sortrows to reorder the data as well.

tic
handsort = sortrows(hands3,3);
toc
handsort(1:8,:)
isequal(handsort, handsr)
Elapsed time is 0.013555 seconds.
ans =
     1     2     3
     1     2     4
     1     3     4
     2     3     4
     1     2     5
     1     3     5
     1     4     5
     2     3     5
ans =
     0

Notice in this case that although the last column is sorted the same as the others, the first two columns come in a different ordering. Plus, I didn't have to do the first transformation of 53-cardvalue. It's not until the 7th row that we can see the difference.

[handsr(7:8,1:3) handsort(7:8,1:3)]
ans =
     2     3     5     1     4     5
     1     4     5     2     3     5

How many rows differ?

sum(any(handsr-handsort,2))
ans =
       21832

Lots of them!

Your Ordering Ideas

Do you need to order data for your work? What are some of the tips you can pass along? Add them here.


Get the MATLAB code

Published with MATLAB® 7.4

11 Responses to “Reordering Arrays”

  1. Steve replied on :

    Am I missing something, or is the duplication in your calculations of handsr and handff a mistake? Did you mean to write the following?

    tic
    handsr = rot90(hands3t,2)
    toc

  2. Loren replied on :

    Steve-

    Good catch and sorry about that. I have updated the blog to show the right version now.

    –Loren

  3. Dan K replied on :

    Hi Loren,
    I’m mightily confused as to how using rot90 is sorting the array so that the cards with the lowest high value are coming up first. Doesn’t rot90(X,2) just flip the array by 180 degrees, preserving the order of the rows? Likewise the flip-flip method seems to do the same thing. Where is the re-ordering occurring?
    -Dan

  4. Loren replied on :

    Dan-

    Flipping IS reordering. It’s not deeper than that.

    –Loren

  5. Dan K replied on :

    Loren,
    To make sure I am understanding. This analysis will then only work in the specific case where the rows are already in order, just backwards. These approaches don’t act to order the data in terms of lowest high value first, that was already done (albeit backwards) by nchoosek. Is this correct?
    Dan

  6. Loren replied on :

    Dan-

    The flipping will work if the data came from nchoosek. It won’t always work. I’m just trying to point people to various tools.

    –Loren

  7. Navaneethan Santhanam replied on :

    Loren,

    I’m trying to run a simulation in which a vector needs to be reordered randomly during each iteration of the simulation. I’ve looked up MATLAB’s help documentation, and can’t seem to find anything.

    To give you an example:
    A = [1.2 3.8 5.7 90 63.7 88.65] and I need to pick 3 numbers from the array randomly without replacement. I’d like to randomly reorder the array and pick the first 3 each time. Is there a built-in function to accomplish the randomising part? Also, is this the most efficient way to do it?

    Navaneethan

  8. Loren replied on :

    Navaneethan-

    Take a look at the function randperm. I think it will do what you need. Something like this:

    
    A = [1.2 3.8 5.7 90 63.7 88.65]
    n = randperm(length(A))
    ind = n(1:3)
    
    

    and repeat the last 2 lines as often as you need.

    –Loren

  9. Navaneethan Santhanam replied on :

    Loren,

    Thank you for the prompt response! I tried your idea out. However, randperm works only on integers, and consequently all values in the vector n are approximated to the nearest integer. Any other thoughts?

    Navaneethan

  10. Loren replied on :

    Use the values as indices into A.

    
    A = [1.2 3.8 5.7 90 63.7 88.65]
    n = randperm(length(A))
    ind = n(1:3)
    B=A(ind)
    

    –Loren

  11. Navaneethan Santhanam replied on :

    Thanks a lot, Loren! That worked perfectly.

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.

  • Ulla Vainio: That error bar width adjustment was extremely useful and I would never have figured it out myself....
  • Peter Perkins: Jessee, there is a property that you can use to tag variables with units. For example, >> load...
  • Jessee: I could potentially see myself using dataset for casually looking at data, but from an application standpoint...
  • Loren: Oktay- It very much depends on the details of the calculations you are doing. Vectorization can sometimes...
  • Oktay: Hello, Is there any significant difference between using: - Vectorization inside a subfunction - Benefiting...
  • Loren: Clare- Yes, sum can sum a double vector: x = [.3 .4 pi/3] y = sum(x) x = 0.3 0.4 1.0472 y = 1.7472 You must...
  • Clare J: R2007a - Student Version When I use sum to sum a vector of type double I get this error message: ???...
  • Sarah Zaranek: Hi Jacob, Sorry about the slow response. You are correct that the code would be slower without the...
  • Navaneethan Santhanam: Thanks a lot, Loren! That worked perfectly.
  • Mike N: Should it be OK to use “persistent 221; variables in a deployed application? What if I have two...

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

Related Topics