3
votes

I have a matrix like

frequencyarray =

    697    697    697    697    697    697      0      0    697
      0      0      0      0      0      0    770    770      0
      0      0      0      0      0      0      0      0      0
      0      0      0      0      0      0      0      0      0
   1209   1209   1209   1209   1209   1209   1209   1209   1209
      0      0      0      0      0      0      0      0      0
      0      0      0      0      0      0      0      0      0

I'd now like to eliminate all the zeros on a vector base from it and get this

frequencyarray2 =

    697    697    697    697    697    697    770    770    697
   1209   1209   1209   1209   1209   1209   1209   1209   1209

I only want to do this if exactly two non-zero numbers are in a vector. If a vector has more or less than two non-zero numbers, they should be replaced with zeros.

Therefore, if I have something like:

frequencyarray =

      0      0    697    697
      0      0    770    770
      0      0      0      0
      0      0      0      0
   1209   1209   1209   1209
      0      0      0      0
      0      0      0      0

the response should be:

frequencyarray2 =

      0      0      0      0

Using find, this doesn't work, it just does everything in on single vector. I thought about using find and then reshape. But that does only work if exactly two numbers are non-zero per vector.

If possible, I'd like to avoid loops. The columns don't have any relation between them.

Any idea is appreciated

3
Not a simple problem - are you sure you want/must solve it vector based?bdecaf
hmm well... that's just the output of the previous part. i could think about changing it though. i guess i'll just use a for if there's no matlab-like-magic way to do thisAtmocreations
well it's two part. as I see it you can treat the lines vectorized - but you still have to iterate over it line - by line. so a "half-vectorized" approach is possible. Also Ali showed you you find "candidate" lines vectorized.bdecaf

3 Answers

2
votes

You can use sum and find together. Something like:

frequencyarray(sum(frequencyarray==0)==2)
1
votes

a helpful code snippet to compare two lines:

all( (frequencyarray(i,:) == 0) & (frequencyarray(i+1,:) ~= 0) ) 

it will be true when all the 0 are non-zero in the following line. The line comparison is vectorized - though you have to move through the array.

To join the lines you could use:

i_cand = (frequencyarray(i,:) == 0
joined_line = frequencyarray(i,:); % start
joined_line(~icand) = frequencyarray(i+1,~icand); % end of joining
0
votes

Well... I've solved the problem. Even not in a way I'd desired, but it works... And it doesn't have to be ultra-fast.

Here's my solution, if someone is interested:

function [collapsed] = collapse(frequencies)
    fsize = size(frequencies,2);
    collapsed = zeros(2,fsize);
    for it=1:fsize
        col = frequencies(:,it);
        nonzero = frequencies(find(col != 0));
        if (size(nonzero,1) == 2)
            collapsed(:,it) = nonzero;
        endif
    endfor
endfunction