# flip the sign at zero crossing point

2 views (last 30 days)
nashat sawai on 3 Oct 2020
Commented: Vladimir Sovkov on 3 Oct 2020
I have an array vector (signal ) contains vales ones and zeros. e.g data set as follow
Data1 = [1,0,1,0,1,0,1,0,1,0];
I want to reverse the sign (phase) of values at zero-crossing points to become as follow
Data1=[1, 0,-1, 0, 1, 0,-1, 0, 1, 0]
do you know an elegant way to do that on a large data set?

Stephen Cobeldick on 3 Oct 2020
>> Data1 = [1,0,1,0,1,0,1,0,1,0]
Data1 =
1 0 1 0 1 0 1 0 1 0
>> Data2 = Data1.*cumprod([1,diff(Data1==0)])
Data2 =
1 0 -1 0 1 0 -1 0 1 0

Show 1 older comment
Vladimir Sovkov on 3 Oct 2020
This algorithm works with only this input vector, for which case it can be done much simpler. If you have two equal elements in a sequence, it produces wrong results. Try Data1 = [1,0,1,0,1,1,0,1,0,1] or Data1 = [1,0,1,0,0,1,0,1,0,1,0].
Stephen Cobeldick on 3 Oct 2020
@Vladimir Sovkov: you are right, the diff can return zero. Luckily this is easily fixed:
>> Data1 = [1,0,0,1,1,0,1,0,1,1,0,0,0,1,0,0]
Data1 =
1 0 0 1 1 0 1 0 1 1 0 0 0 1 0 0
>> D = [1,diff(Data1==0)];
>> D(D==0) = 1;
>> Data2 = Data1 .* cumprod(D)
Data2 =
1 0 0 -1 -1 0 1 0 -1 -1 0 0 0 1 0 0
Vladimir Sovkov on 3 Oct 2020
In my understanding, the sign must alternate between every zero elements. Hence, it must change after the odd number of zeros in a sequence but must not after the even number of zeros. It is not fulfilled yet.

Vladimir Sovkov on 3 Oct 2020
Data1 = [1,0,1,1,0,1,1,0,0,1,0,1,0];
k=find(~Data1);
if ~isempty(k)
if k(end)<numel(Data1)
k(end+1)=numel(Data1)+1;
end
for n=1:2:numel(k)-1
Data1(k(n)+1:k(n+1)-1)=-1;
end
end
disp(Data1);

Stephen Cobeldick on 3 Oct 2020
Simpler:
>> Data1 = [1,0,1,1,0,1,1,0,0,1,0,1,0]
Data1 =
1 0 1 1 0 1 1 0 0 1 0 1 0
>> Data2 = Data1 .* cumprod(1-2*(Data1==0))
Data2 =
1 0 -1 -1 0 1 1 0 0 1 0 -1 0
Vladimir Sovkov on 3 Oct 2020
Yes!