Finding the elements in a list that are less than their successor along with their indices

Please suggest how to write following MALTAB code in Mathematica

k=1;
for j=1:bb-1
if (aa(j)-aa(j+1))<0
cc(k)=aa(j);
dd(k)=j;
k=k+1;
end
end


Here aa is some array and bb is the length of aa.

• A bit rusty on Matlab, but I think k = 1; For[j = 1, j <= bb - 1, j++, If[aa[[j]] - aa[[j + 1]] < 0, cc[[k]] = aa[[j]]; dd[[k]] = j; ] ] would be a literal translation (assuming aa, cc and dd are lists/vectors and the first end closes the If statement with no action if the condition fails... like I said; a bit rusty). But For loops are usually the worst of many, many options in Mathematica. A few more details (ie, what is bb - 1, how long are your vectors, etc) would help people give better answers. Jun 26 '17 at 5:18
• Navdeep, this is almost a duplicate of your other question Find Array Elements That Meet a Condition. Please consider using the answers there to answer your current question. Also, please remember, when you see good questions and answers, to vote them up by clicking the gray triangles, and to accept the answer, if any, that solves your problem by clicking the checkmark sign
– kglr
Jun 26 '17 at 20:04

SeedRandom[1];
aa = RandomInteger[{-10, 10}, 20]
(*{-5, -10, -3, -10, -8, -7, -10, -10, 6, 4, -7, -2, 9, -5, 8, 6, 2, -10, 9, -6}*)


To get the positions, you can use Position and subsequently, to get the elements you can use Extract.

ddc = Position[Differences@aa, _?Positive];
dd = ddc[[All,1]];
cc = Extract[aa, ddc]
(*{-10, -10, -8, -10, -7, -2, -5, -10}*)

• You need to add dd = dd[[All, 1]] at the end to get the dd the OP asked for. Jun 26 '17 at 5:50

This seems to be quite fast:

f1 = Transpose@Pick[Most @ Transpose[{#, Range @ Length @ #}], Sign @ Differences @ #, 1]&;

f1 @ {-5, -10, -3, -10, -8, -7, -10, -10, 6, 4, -7, -2, 9, -5, 8, 6, 2, -10, 9, -6}


{{-10, -10, -8, -10, -7, -2, -5, -10}, {2, 4, 5, 8, 11, 12, 14, 18}}

Update: Timings:

ClearAll[f0, f1, aardvark2012F1, aardvark2012F2, anjanKumarF, eldoF, ubpdqnF]
funcs = {f0, f1, aardvark2012F1, aardvark2012F2, anjanKumarF, eldoF, ubpdqnF};
labels = {"f0", "f1", "aardvark2012F1", "aardvark2012F2", "anjanKumarF", "eldoF", "ubpdqnF"};
results = {res0, res1, res2, res3, res4, res5, res6};

f0[a_] := Pick[#, Sign@Differences@a, 1] & /@ {Most@a, Most@Range@Length@a}
f1[a_] := Transpose@Pick[Most@Transpose[{a, Range@Length@a}], Sign@Differences@a, 1]
aardvark2012F1[a_] := Module[{cc = {}, dd = {}}, Do[If[a[[j]] < a[[j + 1]],
AppendTo[cc, a[[j]]]; AppendTo[dd, j];], {j, Length@a - 1}]; {cc, dd}]
aardvark2012F2[a_] := Transpose@
Table[If[a[[j]] < a[[j + 1]], {a[[j]], j}, ## &[]], {j, Length@a - 1}]
anjanKumarF[a_] := Module[{ddc = Position[Differences@a, _?Positive]},
{Extract[a, ddc], ddc[[All, 1]]}]
eldoF[a_] := Transpose[Flatten[#, 1] &@
Split[MapIndexed[{#, #2[[1]]} &, a], #2[[1]] - #1[[1]] > 0 &][[All, 1 ;; -2]]]
ubpdqnF[a_] := Module[{p = Partition[a, 2, 1]},
Transpose[Thread[Reap[MapIndexed[Sow[#2[[1]], #1[[2]] > #1[[1]]] &, p],
True, {a[[#2]], #2} &][[2, 1]]]]]

Equal @@ (#@{-5, -10, -3, -10, -8, -7, -10, -10, 6, 4, -7, -2, 9, -5,
8, 6, 2, -10, 9, -6} & /@ funcs)


True

SeedRandom[1];
bb = RandomInteger[{-10, 10}, 100000];
timings = Table[First[AbsoluteTiming[results[[j]] = funcs[[j]][bb];]], {j, 7}];
Equal @@ results


True

Transpose[{labels, timings}] //
TableForm[#, TableHeadings -> {None, {"function", "timing"}}] &


Removing the function aardvark2012F1 from the list for a test with a larger input size:

SeedRandom[1];
bb = RandomInteger[{-10, 10}, 1000000];
timings = Table[First[AbsoluteTiming[results[[j]] = funcs[[j]][bb];]],
{j, {1, 2, 4, 5, 6, 7}}];
Equal @@ results[[{1, 2, 4, 5, 6, 7}]]


True

Transpose[{labels[[{1, 2, 4, 5, 6, 7}]], timings}] //
TableForm[#, TableHeadings -> {None, {"function", "timing"}}] &


• Maybe even a little bit faster: Pick[#, Sign@Differences@list, 1] & /@ {Most@list, Most@Range@Length@list}
– eldo
Jun 27 '17 at 16:40
• @eldo, I added the function you suggested.
– kglr
Jun 28 '17 at 15:46

EDIT To dea with clumping from same difference from original code

Just for something different using Reap and Sow and producing list {index,value}:

list = {-5, -10, -3, -10, -8, -7, -10, -10, 6, 4, -7, -2, 9, -5, 8, 6,
2, -10, 9, -6};
p = Partition[list, 2, 1];
MapIndexed[Sow[#2[[1]], #1[[2]] > #1[[1]]] &, p],True,{#2,list[[#2]]} &][[2,1]]]


yielding:

(*{{2, -10}, {4, -10}, {5, -8}, {8, -10}, {11, -7}, {12, -2}, {14, -5},{18, -10}}*)

• @march I hope I have corrected my inadvertent deletion of { (in trying to make it fit on line). Thank you for pointing out my error. Jun 26 '17 at 22:22
• Yeah now it works thanks! Jun 26 '17 at 23:20
list = {-5, -10, -3, -10, -8, -7, -10, -10, 6, 4, -7, -2, 9, -5, 8, 6, 2, -10, 9, -6};

Flatten @ Split[list, Less][[All, 1 ;; -2]]


{-10, -10, -8, -10, -7, -2, -5, -10}

To also get the indices:

Flatten[#, 1]&@
Split[
MapIndexed[{#2[[1]], #1} &, list],
#2[[2]] - #1[[2]] > 0 &][[All, 1 ;; -2]]


{{2, -10}, {4, -10}, {5, -8}, {8, -10}, {11, -7}, {12, -2}, {14, -5}, {18, -10}}

• The indices also were requested. Jun 26 '17 at 15:13

Taking

bb = 20;
SeedRandom[1];
aa = RandomInteger[{-10, 10}, bb];


Here are two possibilities:

cc = {}; dd = {};
Do[
If[aa[[j]] < aa[[j + 1]],
AppendTo[cc, aa[[j]]];
AppendTo[dd, j];
],
{j, bb - 1}
]
cc
dd

(* cc = {-10, -10, -8, -10, -7, -2, -5, -10}
dd = {2, 4, 5, 8, 11, 12, 14, 18} *)


Or alternatively,

{cc, dd} =
Transpose@
Table[If[aa[[j]] < aa[[j + 1]], {aa[[j]], j}, Nothing], {j, bb - 1}]

(* {{-10, -10, -8, -10, -7, -2, -5, -10}, {2, 4, 5, 8, 11, 12, 14, 18}} *)

• Thanks to all for providing solutions Jun 26 '17 at 7:23
• @NavdeepGoel No worries. Don't forget to select one by clicking on the tick. Jun 26 '17 at 8:14