NestWhileList[f,x,test] lets you iterate a function until a condition is satisfied, outputting the list of iterated values

    In[1]:= NestWhileList[f,x,test]

    Out[1]:= {x,f[x],f[f[x]],f[f[f[x]]], ... }

If the objects produced Nest[f,x,n] are large, and require a lot of storage space, and one only requires some small amount of data captured by g[Nest[f,x,n]], one would like a function

    In[2]:= NestPairWhileList[f,x,test,g]

    Out[2]:= {g[x],g[f[x]],g[f[f[x]]],g[f[f[f[x]]]], ... }

is there a simple and efficient way to implement this operation?

This is similar to the relationship between FoldList and FoldPairList, but without requiring the a priori knowledge of the number of iterations.

Naive guess at answer

I can see that one can do

    In[3]:= NestPairWhileList[f_, x_, test_, g_] := g/@NestWhileList[f,x,test]

to produce the correct output, but I do not expect this to be memory efficient as it requires producing the entire output of NestWhileList.

  • 2
    $\begingroup$ perhaps nPWL1[f_, x_, test_, g_] := Reap[NestWhileList[Sow@f[##] &, x, test], _, g /@ #2 &][[2]]? $\endgroup$ – kglr Apr 11 '20 at 1:39
  • 2
    $\begingroup$ ... or nPWL2[f_, x_, test_, g_] := Reap[NestWhileList[(Sow[g[#]]; #) &@f[##] &, x, test]][[2]]? $\endgroup$ – kglr Apr 11 '20 at 1:39

The function

    In[4]:= NestPairWhileList[f_, x_, test_, g_] := ...

        ... Join[#[[1, 1]],{#[[2]]}]&@Reverse@Reap@g@NestWhile[(Sow[g[#]]; f[#]) &, x, test]

seems to return the right results. Though maybe there are better ways to do this.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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