# How to discard values from a matrix (column) using specific conditions

EXPLANATION OF THE PROBLEM: I have an oscillating function, defined as $f(x)$; that function is also “periodic”, with period T and $f(x)=f(x+T)$. The function is also characterized by a certain number N of oscillations in the domain 0 ≤ x ≤ T. Moreover this function, with 0 ≤ x ≤ T , has a certain number of peaks and troughs (that should be equal to N). In this case, $f(x)$ is studied in the domain $X_{firstpeak} ≤ x ≤ X_{lastpeak}$, with ( $X_{lastpeak} - X_{firstpeak}) = T$ and $f(X_{firstpeak} ) = f(X_{lastpeak})$. Using FindPeaks it is possible to obtain the values of the variable x at which the function reaches a peak or a trough. the values obtained are

Xpeaks = {{0.12}, {0.42}, {0.62}, {0.68}, {1.08}, {1.5}, \
{1.96}, {2.2}, {2.48}, {2.76}, {3.06}, {3.38}, {3.64}, \
{3.84}, {4.4}, {4.8}, {5.4}, {5.68}, {5.92}, {6.46}, {6.72}, \
{7.22}, {7.74}, {8.22}, {8.74}, {9.32}, {9.74}, {10.08}, \
{10.44}, {10.84}, {11.06}, {11.6}, {12.24}, {12.78}, {13.2}, \
{13.48}, {13.84}, {14.18}, {14.80}, {15.06}, {15.38}, {15.7}, \
{16.24}, {16.62}, {17.04}, {17.24}, {17.56}, {18.}, {18.46}, \
{18.76}, {19.06}, {19.52}, {19.92}, {20.5}, {20.94}, {21.46}, \
{21.92}, {22.42}, {22.86}}

Xtroughs = {{0.3}, {0.46}, {0.8}, {1.30}, {1.68}, {1.79}, \
{2.1}, {2.38}, {2.68}, {2.90}, {3.28}, {3.46}, {3.90}, \
{4.66}, {5.04}, {5.56}, {5.76}, {6.22}, {6.60}, {6.88}, \
{6.99}, {7.03}, {7.4}, {8.02}, {8.44}, {9.}, {9.58}, {9.92}, \
{10.26}, {10.6}, {10.94}, {11.2}, {11.86}, {12.46}, {12.98}, \
{13.32}, {13.68}, {13.96}, {14.44}, {14.92}, {15.2}, {15.48}, \
{16.06}, {16.34}, {16.86}, {17.12}, {17.42}, {17.76}, {18.3}, \
{18.62}, {18.92}, {19.26}, {19.68}, {20.34}, {20.64}, {21.24}, \
{21.78}, {22.16}, {22.20}, {22.64}}

In[8]:= First[Dimensions[Xpeaks]]

Out[8]= 59

In[9]:= First[Dimensions[Xtroughs]]

Out[9]= 60


As we can see the dimensions of the two columns are different. Moreover it can be observed that Dimensions[Xpeaks] should be equal to Dimensions[Xtroughs] + 1, because the first and the last value of Xpeaks are describing the same peak (they are the limits of the domain). And it should be also Dimensions[Xtroughs] = N . However it seems that for a single oscillation (using FindPeaks) in some cases Mathematica finds more than one peak value (or “more than one trough value”). Ps. I can not change the options of FindPeaks, I just want to play with the two columns obtained.

NOW THE QUESTION IS How can I delate values from Xpeaks and Xtroughs in order to obtain one single peak and one single trough for every oscillation? It means that at the end, using

Riffle[Xpeaks, Xtroughs]


I should be able to obtain a column with all the values in an ascending order. Just to be clear, in Xpeaks I’d like to delete the following values {0.68}, {3.84} ; while in Xtroughs I’d like to delete {1.79}, {6.99}, {7.03}, {22.20}.

Anyone can help me? Is there a way to delete those values automatically?

{troughs, peaks} =
SortBy[
GatherBy[First /@
SplitBy[
First],
Last],
Last],
#[[1, -1]] &][[All, All, 1]]


{{0.3, 0.46, 0.8, 1.3, 1.68, 2.1, 2.38, 2.68, 2.9, 3.28, 3.46, 3.9, 4.66, 5.04, 5.56, 5.76, 6.22, 6.6, 6.88, 7.4, 8.02, 8.44, 9., 9.58, 9.92, 10.26, 10.6, 10.94, 11.2, 11.86, 12.46, 12.98, 13.32, 13.68, 13.96, 14.44, 14.92, 15.2, 15.48, 16.06, 16.34, 16.86, 17.12, 17.42, 17.76, 18.3, 18.62, 18.92, 19.26, 19.68, 20.34, 20.64, 21.24, 21.78, 22.16, 22.64},
{0.12, 0.42, 0.62, 1.08, 1.5, 1.96, 2.2, 2.48, 2.76, 3.06, 3.38, 3.64, 4.4, 4.8, 5.4, 5.68, 5.92, 6.46, 6.72, 7.22, 7.74, 8.22, 8.74, 9.32, 9.74, 10.08, 10.44, 10.84, 11.06, 11.6, 12.24, 12.78, 13.2, 13.48, 13.84, 14.18, 14.8, 15.06, 15.38, 15.7, 16.24, 16.62, 17.04, 17.24, 17.56, 18., 18.46, 18.76, 19.06, 19.52, 19.92, 20.5, 20.94, 21.46, 21.92, 22.42, 22.86}}

Complement[Flatten@Xpeaks, peaks]


{0.68, 3.84}

Complement[Flatten@Xtroughs, troughs]


{1.79, 6.99, 7.03, 22.2}

Update: Slightly more streamlined version

sorted = SortBy[Join@@(Thread /@ {{Flatten@Xpeaks, 1}, {Flatten@Xtroughs, 0}}), First];
deleted = sorted[[Join@@(Rest/@SplitBy[Range[Length@sorted], sorted[[All, -1]][[#]] &])]];

{deletedpeaks, deletedtroughs} = SortBy[GatherBy[deleted, Last], Last][[All, All, 1]]
`

{{0.68, 3.84},
{1.79, 6.99, 7.03, 22.2}}

• it works perfectly, thanks! :-) – Nicoma89 May 5 '18 at 18:37
• @Nicoma89, my pleasure. Thank you for the accept. – kglr May 5 '18 at 20:44