Take the 2-minute tour ×
Mathematics Stack Exchange is a question and answer site for people studying math at any level and professionals in related fields. It's 100% free, no registration required.

I'm using MatLab. I am new to it, and new to matrix calculation, too.

Consider the following matrix :

a =

     1     4
     5    12
    20    30
    31    34
    40    50

It represent ranges of data. I need thes range to be continuous. The result should be :

a =

     1     4
     5    12
    13    19
    20    30
    31    34
    35    39
    40    50

I inseted the ranges 13 - 19 and 35 - 39 so that any number between a(1,1) and a(size(a,1) , size(a,2)) can be associated to a single row.

I want to do it, ideally, without for loops.

Any clue?

share|improve this question

1 Answer 1

up vote 1 down vote accepted

The following works. I'll use a shorter example than you, not so much to write, we will use \[ a = \begin{bmatrix} 1 & 2 \\ 3 & 6 \\ 9 & 13 \end{bmatrix} \] First we will add a first column contating the old first column -1 and a last column containing the number following the old last number. The idea is that we want to compare these two numbers to check whether they form an interval (the transpose is due to how Matlab handels step 2):

a = [ a(:, 1)-1, a, a(:,2) + 1]';

We now have \[ a = \begin{bmatrix} 0 & 2 & 8\\ 1 & 3 & 9 \\ 2 & 6 & 13\\ 3 & 7 & 14 \end{bmatrix} \] Now we transform $a$ to a row vector throwing away the first and last element (we don't need them). This is why we had to transpose $a$ in the first step (as Matlab does this columnwise)

a = a(2:length(a(:))-1);

Now \[ a = \begin{bmatrix} 1 & 2 & 3 & 2 & 3 & 6 & 7 & 8 & 9 & 13 \end{bmatrix} \] if we split this into intervals there are legal ones like $[1,2]$ and illegal ones like $[3,2]$. The next two steps will find the first indices of the illegal ones and remove them afterwards.

I   = find(a(1:length(a)-1) > a(2:length(a)));
a([I, I + 1]) = [];

We got \[ a = \begin{bmatrix} 1 & 2 & 3 & 6 & 7 & 8 & 9 & 13 \end{bmatrix} \] Now we just have to reshape $a$ as a matrix again, undoing the transpose we did in the beginning

a = reshape(a, 2, length(a)/2)';

giving \[ a = \begin{bmatrix} 1 & 2 \\ 3 & 6 \\ 7 & 8 \\ 9 & 13 \end{bmatrix} \] I hope I understand correctly what you wanted to do, the program itself may not be the nicest solution, but it uses no for-loops directly :)

share|improve this answer
1  
or simply r=unique([a(:,1)' a(:,2)'+1]); [r(1:end-1);r(2:end)-1]' –  karakfa Jun 22 '12 at 18:34
    
That seems to work just fine. I have solve my problem in a totally different way meanwhile, so I will not use it, but I will test anyway when I return to work where matlab is installed. karakfa's line, too. Thanks. –  Johnny5 Jun 23 '12 at 22:01
    
@karakfa solution is damn straight foward, but since he does not put that as an answer, you got the star ;) –  Johnny5 Jun 26 '12 at 12:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.