Skip to main content
8 of 11
deleted 24 characters in body
DavidC
  • 16.9k
  • 1
  • 43
  • 96

Zeros can be removed from the original list, provided that we keep track of the positions of the remaining numbers. Then we only need to detect when the sign changes from one remaining number to the next.

zeroCrossings[l_] := Module[{z, d, c}, z[v_] := Complement[Range[Length[v]], Flatten@Position[v, 0]]; c = z[l]; d = Differences[Sign@l[[c]]]; c[[{#, # + 1}]] & /@ z[d]] 

Example

Using whuber's list:

zeroCrossings[{0, -1, 1, -2, 0, 0, -1, 0, 0, 0, 1, 0, 1, 0, 2, -1, -3, 0, 0}] 

{{2, 3}, {3, 4}, {7, 11}, {15, 16}}


Analysis

The list:

l = {0, -1, 1, -2, 0, 0, -1, 0, 0, 0, 1, 0, 1, 0, 2, -1, -3, 0, 0} 

Positions of the non-zero values in the list:

Complement[Range[Length[l]], Flatten@Position[l, 0]] 

{2, 3, 4, 7, 11, 13, 15, 16, 17}


The Non-zero numbers themselves:

l[[%]] 

{-1, 1, -2, -1, 1, 1, 2, -1, -3}


Signs of the non-zero numbers:

Sign[%] 

{-1, 1, -1, -1, 1, 1, 1, -1, -1}


Differences between the signs of the non-zero numbers. Non-zero differences, of which there are 4, signal zero-crossings.

Differences[%] 

{2, -2, 0, 2, 0, 0, -2, 0}


Starting positions for the zero-crossings :

Complement[Range[Length[%]], Flatten@Position[%, 0]] 

{1, 2, 4, 7}


The positions where the zero crossings begin:

{2, 3, 4, 7, 11, 13, 15, 16, 17}[[%]] 

{2, 3, 7, 15}

DavidC
  • 16.9k
  • 1
  • 43
  • 96