5
$\begingroup$

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.

$\endgroup$
2
  • $\begingroup$ 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. $\endgroup$ Jun 26, 2017 at 5:18
  • 2
    $\begingroup$ 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 $\endgroup$
    – kglr
    Jun 26, 2017 at 20:04

5 Answers 5

7
$\begingroup$
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}*)
$\endgroup$
1
  • 1
    $\begingroup$ You need to add dd = dd[[All, 1]] at the end to get the dd the OP asked for. $\endgroup$
    – m_goldberg
    Jun 26, 2017 at 5:50
6
$\begingroup$

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"}}] &

Mathematica graphics

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"}}] &

Mathematica graphics

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

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];
Thread[Reap[
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}}*)
$\endgroup$
2
  • $\begingroup$ @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. $\endgroup$
    – ubpdqn
    Jun 26, 2017 at 22:22
  • $\begingroup$ Yeah now it works thanks! $\endgroup$
    – march
    Jun 26, 2017 at 23:20
2
$\begingroup$
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}}

$\endgroup$
1
  • $\begingroup$ The indices also were requested. $\endgroup$
    – bbgodfrey
    Jun 26, 2017 at 15:13
1
$\begingroup$

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}} *)
$\endgroup$
2
  • $\begingroup$ Thanks to all for providing solutions $\endgroup$ Jun 26, 2017 at 7:23
  • $\begingroup$ @NavdeepGoel No worries. Don't forget to select one by clicking on the tick. $\endgroup$ Jun 26, 2017 at 8:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.