# Working with calculations that depend on the previous value in a list

I'm trying to make calculations on a list that depend on the previous value. In my case I'm doing event detection - detecting the point where a value rises above some threshold for the first time

e.g.

list[t]=SomeFunction[list[t-1] ];


A perfect general example would be calculating a fibonacci number non-recursively.

fib[0]=0
fib[1]=1
fib[n]= fib[n-1]+fib[n-2]


If my function just took the value at t I could simply use Map. But I need to work with the value at t-1.

What's the right (functional/mathematica) way to do this? I'm sure there's a way built into mathematica for this, I'm just not finding it in the documentation.

stream = {1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1};
stream[[6]] > 5 &&  stream[[5]] <= 5


Update: Expanding from my concrete example a bit. There are many algorithms and formula, which rely on e.g. the previous or n-1 values in their calculation.

Map is a very simple way to transform a list by a function. Is there an equivalent, elegant, method to do the same where the function may need previous (or n-1, neighbouring) values?

A perfect general example would be calculating a fibonacci number non-recursively.

fib[0]=0
fib[1]=1
fib[n]= fib[n-1]+fib[n-2]


Many ways (for example MapIndexed[]) but you may have some fun using for example @Leonid's implementation of FoldWhile[] here

stream = {0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1};
FoldWhile[#2 &, ! (#1 <= 5 && #2 > 5) &, 0, stream]
(* 5 *)


Here is how it works:

Grid @@@ Reap@
FoldWhile[(Sow[{"Current", #2, " ", "Previous", #1}]; #2) &, ! (#1 <= 5 && #2 > 5) &, 18, stream]


Perhaps

stream = {1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1};

LengthWhile[stream, # <= 5 &]
(* 5 *)
TakeWhile[stream, # <= 5 &]
(* {1,2,3,4,5} *)


or

First[Split[stream , #1 < 5 &]]
(* {1,2,3,4,5} *)
Length@First@Split[stream , #1 < 5 &]
(* 5 *)


or

i = 1; While[stream[[i]] < 5, i++]; i
(* 5 *)
i = 1; While[stream[[i]] < 5, i++]; stream[[;; i]]
(* {1,2,3,4,5} *)


or

(* foo @@@ Transpose[{Most@stream , Rest@stream}] *)
Boole[# <= 5 < #2] & @@@ Transpose[{Most@stream , Rest@stream}]
(* {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} *)


I am not sure what it is you are trying to do, but presumably list = foo /@ RotateRight[list] is something like what you want?!

The most general solution involves the function ListConvolve[] which you should look up (the documentation gives you better examples than the ones I can come up with without knowing what it is you want to do). You want the second last usage (replacing Plus and Times with functions of your own).

• Aside from a serious typo that's rather a comment than an answer. Why don't you show the output of your construction?
– eldo
Sep 19, 2014 at 18:35
• That's essentially the same as Map. Another way to phrase what I'm looking for would be Mapping a list, which allows my function to look up other values in the list, rather than just the value it's working on.
– user4860
Sep 19, 2014 at 18:41
• RotateRight has the effect of looking up an adjacent value. RotateLeft would look up the value from the other side. Do you want more general lookup? Sep 19, 2014 at 18:45