4
votes

I have a 1x1033 column vector in MATLAB that mostly consists of zeros - every so often, there are two numbers adjacent to one another that are either side of zero (i.e. if the first number is positive, the second is negative and vice versa). I am trying to input zeros between these two values without adding zeros at any other point in the matrix. I thought I had it, but my loop only adds a zero between the first two non-zero values, and ignores the rest.

Any help would be appreciated.

my code is shown below: for h = n:-1:1; zero_crossing_markers(h);

if zero_crossing_markers(h) > 0 && zero_crossing_markers(h+1) < 0;
    %zero_values_added = [zero_crossing_markers(1:h), 0, zero_crossing_markers(h+1:n)];
    A = zero_crossing_markers(1:h);
    B = 0;
    C = zero_crossing_markers(h+1:n);
    zero_values_added = [A, B, C];

    else if zero_crossing_markers(h) < 0 && zero_crossing_markers(h+1) > 0;
        %zero_values_added = [zero_crossing_markers(1:h), 0, zero_crossing_markers(h+1:n)];
        A = zero_crossing_markers(1:h);
        B = 0;
        C = zero_crossing_markers(h+1:n);
        zero_values_added = [A, B, C];

    else
        zero_values_added(h) = 0;
        end
end

end

2

2 Answers

2
votes

No loops needed. It can be solved in a vectorized manner, in one line:

clear result
data = [1 -2 0 0 0 2 -3 0 0 5 -1 2 0 1 1]; %// example data

result((1:numel(data)) + [0 cumsum(abs(diff(sign(data)))==2)]) = data;

For this example,

result =
  Columns 1 through 15
     1     0    -2     0     0     0     2     0    -3     0     0     5     0    -1     0
  Columns 16 through 19
     2     0     1     1

How this works: the idea is to stretch data into result so that zeros get automatically inserted. The places in which a stretching will occurr, and in which a zero will be inserted, are obtained from abs(diff(sign(data)))==2: a 1 value in this vector indicates that the following position should be an inserted zero. cumsum is used for accumulating all stretchings.

1
votes

This does the trick:

x = [0 1 -2 0 3 -4 0 0]';
y = zeros(size(x,1) + nnz(x>0),1);
ix = find(x > 0);
ix = ix + (0:numel(ix) - 1)'
ix2 = ix + 2;
y(ix) = x(x > 0);
y(ix2) = x(x < 0);
y =
     0
     1
     0
    -2
     0
     3
     0
    -4
     0
     0