0
$\begingroup$

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?

$\endgroup$
1
$\begingroup$

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 :)

$\endgroup$
3
  • 1
    $\begingroup$ or simply r=unique([a(:,1)' a(:,2)'+1]); [r(1:end-1);r(2:end)-1]' $\endgroup$ – karakfa Jun 22 '12 at 18:34
  • $\begingroup$ 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. $\endgroup$ – Johnny5 Jun 23 '12 at 22:01
  • $\begingroup$ @karakfa solution is damn straight foward, but since he does not put that as an answer, you got the star ;) $\endgroup$ – Johnny5 Jun 26 '12 at 12:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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