From: Francisco Gutierrez on 20 Jan 2010 06:49 Dear group: I have a function that gets five arguments, two of which are fixed, and three vary. Its output are three numbers. So it can be nested, for example over some initial values. Say: Nest[func[arg1,arg2,#[[1]],#[[2]],#[[3]]]&,{init1,init2,init3},k] Simple enough, works well. Now I want to nest the same function, while the second non fixed argument changes at each step. I thought the "natural" way of doing this was: NestWhile[func[arg1,arg2,#[[1]],#[[2]],#[[3]]]&,{init1,init2,init3},UnsameQ[#[[2]]&,2], but this evidently does not work. So: in a NestWhile how do I create tests over parts of the outputs of a function? Thanks! Fg
From: Leonid Shifrin on 21 Jan 2010 04:49 Hi Francisco, When you use NestWhile and wish to access several past results, they should correspond to different arguments of your test function. Here is some specific function: Clear[func]; func[x_, y_, z_, p_, q_] := IntegerPart[{z, p, q}^0.9] Here is how we can use it to achieve what you want: In[2]:= NestWhileList[ func[1, 2, #[[1]], #[[2]], #[[3]]] &, {1, 100, 1000}, UnsameQ[#1[[2]], #2[[2]]] &, 2] Out[2]= {{1, 100, 1000}, {1, 63, 501}, {1, 41, 269}, {1, 28, 153}, {1, 20, 92}, {1, 14, 58}, {1, 10, 38}, {1, 7, 26}, {1, 5, 18}, {1, 4, 13}, {1, 3, 10}, {1, 2, 7}, {1, 1, 5}, {1, 1, 4}} I used NestWhileList to make it more transparent what's going on. Or, in this case, it may be less confusing to use pure function with named arguments for the test: In[3]:= NestWhileList[ func[1, 2, #[[1]], #[[2]], #[[3]]] &, {1, 100, 1000}, Function[{this, prev}, UnsameQ[this[[2]], prev[[2]]]], 2] Out[3]= {{1, 100, 1000}, {1, 63, 501}, {1, 41, 269}, {1, 28, 153}, {1, 20, 92}, {1, 14, 58}, {1, 10, 38}, {1, 7, 26}, {1, 5, 18}, {1, 4, 13}, {1, 3, 10}, {1, 2, 7}, {1, 1, 5}, {1, 1, 4}} Note that the first argument is the "oldest" result and the last argument is the most recent one, and the total number of arguments to the test function is regulated by the fourth parameter to NestWhile(List) - 2 in our case. Note also that pure functions silently ignore excessive arguments passed to them. These two facts imply that you may get obscure mistakes if you specify the wrong (too large) number of most recent results *and* use a pure function for testing. Hope this helps. Regards, Leonid On Wed, Jan 20, 2010 at 2:50 PM, Francisco Gutierrez <fgutiers2002(a)yahoo.com > wrote: > Dear group: > I have a function that gets five arguments, two of which are fixed, and > three vary. Its output are three numbers. So it can be nested, for example > over some initial values. > Say: > Nest[func[arg1,arg2,#[[1]],#[[2]],#[[3]]]&,{init1,init2,init3},k] > > Simple enough, works well. > Now I want to nest the same function, while the second non fixed argument > changes at each step. I thought the "natural" way of doing this was: > > NestWhile[func[arg1,arg2,#[[1]],#[[2]],#[[3]]]&,{init1,init2,init3},UnsameQ[#[[2]]&,2], > but this evidently does not work. > > So: in a NestWhile how do I create tests over parts of the outputs of a > function? > Thanks! > Fg > >
From: Leonid Shifrin on 21 Jan 2010 04:50 Francisco, This is a follow-up to my previous post. To be logically correct, the example I gave with a test function with named arguments had to be with the order of arguments interchanged: Function[{prev, this}, UnsameQ[this[[2]], prev[[2]]]] instead of Function[{this, prev}, UnsameQ[this[[2]], prev[[2]]]] Sorry for the confusion. Regards, Leonid On Wed, Jan 20, 2010 at 2:50 PM, Francisco Gutierrez <fgutiers2002(a)yahoo.com > wrote: > Dear group: > I have a function that gets five arguments, two of which are fixed, and > three vary. Its output are three numbers. So it can be nested, for example > over some initial values. > Say: > Nest[func[arg1,arg2,#[[1]],#[[2]],#[[3]]]&,{init1,init2,init3},k] > > Simple enough, works well. > Now I want to nest the same function, while the second non fixed argument > changes at each step. I thought the "natural" way of doing this was: > > NestWhile[func[arg1,arg2,#[[1]],#[[2]],#[[3]]]&,{init1,init2,init3},UnsameQ[#[[2]]&,2], > but this evidently does not work. > > So: in a NestWhile how do I create tests over parts of the outputs of a > function? > Thanks! > Fg > >
From: DrMajorBob on 22 Jan 2010 05:38 How about Clear[func,func2, test] func[x_, y_, z_, p_, q_] := IntegerPart[{z, p, q}^0.9] func2[x_, y_][{z_, p_, q_}] := func[x, y, z, p, q] test[{_, a_, _}, {_, b_, _}] := UnsameQ[a, b] NestWhileList[func2[1, 2], {1, 100, 1000}, test, 2] {{1, 100, 1000}, {1, 63, 501}, {1, 41, 269}, {1, 28, 153}, {1, 20, 92}, {1, 14, 58}, {1, 10, 38}, {1, 7, 26}, {1, 5, 18}, {1, 4, 13}, {1, 3, 10}, {1, 2, 7}, {1, 1, 5}, {1, 1, 4}} or Clear[func3, test] func3[{z_, p_, q_}] := IntegerPart[{z, p, q}^0.9] test[{_, a_, _}, {_, b_, _}] := UnsameQ[a, b] NestWhileList[func3, {1, 100, 1000}, test, 2] {{1, 100, 1000}, {1, 63, 501}, {1, 41, 269}, {1, 28, 153}, {1, 20, 92}, {1, 14, 58}, {1, 10, 38}, {1, 7, 26}, {1, 5, 18}, {1, 4, 13}, {1, 3, 10}, {1, 2, 7}, {1, 1, 5}, {1, 1, 4}} Bobby On Thu, 21 Jan 2010 03:50:03 -0600, Leonid Shifrin <lshifr(a)gmail.com> wrote: > Hi Francisco, > > When you use NestWhile and wish to access several past results, they > should > correspond to different arguments of your test function. > > Here is some specific function: > > Clear[func]; > func[x_, y_, z_, p_, q_] := IntegerPart[{z, p, q}^0.9] > > Here is how we can use it to achieve what you want: > > In[2]:= NestWhileList[ > func[1, 2, #[[1]], #[[2]], #[[3]]] &, {1, 100, 1000}, > UnsameQ[#1[[2]], #2[[2]]] &, 2] > > Out[2]= {{1, 100, 1000}, {1, 63, 501}, {1, 41, 269}, {1, 28, > 153}, {1, 20, 92}, {1, 14, 58}, {1, 10, 38}, {1, 7, 26}, {1, 5, > 18}, {1, 4, 13}, {1, 3, 10}, {1, 2, 7}, {1, 1, 5}, {1, 1, 4}} > > I used NestWhileList to make it more transparent what's going on. Or, in > this case, it may be less confusing to use pure function with named > arguments for the test: > > In[3]:= NestWhileList[ > func[1, 2, #[[1]], #[[2]], #[[3]]] &, {1, 100, 1000}, > Function[{this, prev}, UnsameQ[this[[2]], prev[[2]]]], 2] > > Out[3]= {{1, 100, 1000}, {1, 63, 501}, {1, 41, 269}, {1, 28, > 153}, {1, 20, 92}, {1, 14, 58}, {1, 10, 38}, {1, 7, 26}, {1, 5, > 18}, {1, 4, 13}, {1, 3, 10}, {1, 2, 7}, {1, 1, 5}, {1, 1, 4}} > > Note that the first argument is the "oldest" result and the last > argument is > the most recent one, and the total number of arguments to the test > function > is regulated by the fourth parameter to NestWhile(List) - 2 in our case. > Note also that pure functions silently ignore excessive arguments passed > to > them. These two facts imply that you may get obscure mistakes if you > specify > the wrong (too large) number of most recent results *and* use a pure > function for testing. > > Hope this helps. > > Regards, > Leonid > > > On Wed, Jan 20, 2010 at 2:50 PM, Francisco Gutierrez > <fgutiers2002(a)yahoo.com >> wrote: > >> Dear group: >> I have a function that gets five arguments, two of which are fixed, and >> three vary. Its output are three numbers. So it can be nested, for >> example >> over some initial values. >> Say: >> Nest[func[arg1,arg2,#[[1]],#[[2]],#[[3]]]&,{init1,init2,init3},k] >> >> Simple enough, works well. >> Now I want to nest the same function, while the second non fixed >> argument >> changes at each step. I thought the "natural" way of doing this was: >> >> NestWhile[func[arg1,arg2,#[[1]],#[[2]],#[[3]]]&,{init1,init2,init3},UnsameQ[#[[2]]&,2], >> but this evidently does not work. >> >> So: in a NestWhile how do I create tests over parts of the outputs of a >> function? >> Thanks! >> Fg >> >> -- DrMajorBob(a)yahoo.com
From: Leonid Shifrin on 22 Jan 2010 05:39 Hi Bobby, Well, these are certainly the possibilities, I just wanted to stay as close to the original code of Francisco as possible. Removing this restriction, conceptually your first example is better than my version since it clearly separates the fixed and varying arguments. FWIW, your second version is not up to Fransisco's specs, since he asked that his function explicitly takes 5 args and keeps the first two fixed, while in your second example the function takes only three. Defiining the test function through patterns, besides being easier to read, seems to me a step in the right direction in avoiding the kind of errors I mentioned (if that was the goal), but in the form you have it it does seem to properly do so, since every outcome of the test function which is not explicitly True is considered to be False by NestWhile(List), the behavior which more likely than not is not what is desired: In[1]:= Clear[func, func2, test]; func[x_, y_, z_, p_, q_] := IntegerPart[{z, p, q}^0.9] func2[x_, y_][{z_, p_, q_}] := func[x, y, z, p, q] test[{_, a_, _}, {_, b_, _}] := UnsameQ[a, b] NestWhileList[func2[1, 2], {1, 100, 1000}, test, 3] Out[1] = {{1, 100, 1000}, {1, 63, 501}, {1, 41, 269}} If this (bullet-proofing) is at all an issue, I'd probably do it this way: In[2]:= ClearAll[func, func2, test] test::argnum = "test was called with `1` arguments. Two arguments were expected"; func[x_, y_, z_, p_, q_] := IntegerPart[{z, p, q}^0.9] func2[x_, y_][{z_, p_, q_}] := func[x, y, z, p, q] test[{_, a_, _}, {_, b_, _}] := UnsameQ[a, b]; test[x___] := (Message[test::argnum, Length[{x}]]; Throw[$Failed]); In[3]:= Catch(a)NestWhileList[func2[1, 2], {1, 100, 1000}, test, 3] During evaluation of In[3]:= test::argnum: test was called with 3 arguments. Two arguments were expected Out[3]= $Failed This does not seem to make much sense here, but may make sense if different test functions requiring different number of most recent results are expected to be used, like here: Clear[getFixedPoint] getFixedPoint[start : {_, _, _}, testF_, testParNum_] := Catch(a)NestWhileList[func2[1, 2], start, testF, testParNum]; This will then guard against the wrong combination of testF and testParNum being passed to getFixedPoint. Regards, Leonid On Thu, Jan 21, 2010 at 9:31 PM, DrMajorBob <btreat1(a)austin.rr.com> wrote: > How about > > Clear[func,func2, test] > > func[x_, y_, z_, p_, q_] := IntegerPart[{z, p, q}^0.9] > func2[x_, y_][{z_, p_, q_}] := func[x, y, z, p, q] > test[{_, a_, _}, {_, b_, _}] := UnsameQ[a, b] > NestWhileList[func2[1, 2], {1, 100, 1000}, test, 2] > > > {{1, 100, 1000}, {1, 63, 501}, {1, 41, 269}, {1, 28, 153}, {1, 20, > 92}, {1, 14, 58}, {1, 10, 38}, {1, 7, 26}, {1, 5, 18}, {1, 4, > 13}, {1, 3, 10}, {1, 2, 7}, {1, 1, 5}, {1, 1, 4}} > > or > > Clear[func3, test] > func3[{z_, p_, q_}] := IntegerPart[{z, p, q}^0.9] > test[{_, a_, _}, {_, b_, _}] := UnsameQ[a, b] > NestWhileList[func3, {1, 100, 1000}, test, 2] > > > {{1, 100, 1000}, {1, 63, 501}, {1, 41, 269}, {1, 28, 153}, {1, 20, > 92}, {1, 14, 58}, {1, 10, 38}, {1, 7, 26}, {1, 5, 18}, {1, 4, > 13}, {1, 3, 10}, {1, 2, 7}, {1, 1, 5}, {1, 1, 4}} > > Bobby > > > On Thu, 21 Jan 2010 03:50:03 -0600, Leonid Shifrin <lshifr(a)gmail.com> > wrote: > > Hi Francisco, >> >> When you use NestWhile and wish to access several past results, they >> should >> correspond to different arguments of your test function. >> >> Here is some specific function: >> >> Clear[func]; >> func[x_, y_, z_, p_, q_] := IntegerPart[{z, p, q}^0.9] >> >> Here is how we can use it to achieve what you want: >> >> In[2]:= NestWhileList[ >> func[1, 2, #[[1]], #[[2]], #[[3]]] &, {1, 100, 1000}, >> UnsameQ[#1[[2]], #2[[2]]] &, 2] >> >> Out[2]= {{1, 100, 1000}, {1, 63, 501}, {1, 41, 269}, {1, 28, >> 153}, {1, 20, 92}, {1, 14, 58}, {1, 10, 38}, {1, 7, 26}, {1, 5, >> 18}, {1, 4, 13}, {1, 3, 10}, {1, 2, 7}, {1, 1, 5}, {1, 1, 4}} >> >> I used NestWhileList to make it more transparent what's going on. Or, in >> this case, it may be less confusing to use pure function with named >> arguments for the test: >> >> In[3]:= NestWhileList[ >> func[1, 2, #[[1]], #[[2]], #[[3]]] &, {1, 100, 1000}, >> Function[{this, prev}, UnsameQ[this[[2]], prev[[2]]]], 2] >> >> Out[3]= {{1, 100, 1000}, {1, 63, 501}, {1, 41, 269}, {1, 28, >> 153}, {1, 20, 92}, {1, 14, 58}, {1, 10, 38}, {1, 7, 26}, {1, 5, >> 18}, {1, 4, 13}, {1, 3, 10}, {1, 2, 7}, {1, 1, 5}, {1, 1, 4}} >> >> Note that the first argument is the "oldest" result and the last argument >> is >> the most recent one, and the total number of arguments to the test >> function >> is regulated by the fourth parameter to NestWhile(List) - 2 in our case. >> Note also that pure functions silently ignore excessive arguments passed >> to >> them. These two facts imply that you may get obscure mistakes if you >> specify >> the wrong (too large) number of most recent results *and* use a pure >> function for testing. >> >> Hope this helps. >> >> Regards, >> Leonid >> >> >> On Wed, Jan 20, 2010 at 2:50 PM, Francisco Gutierrez < >> fgutiers2002(a)yahoo.com >> >>> wrote: >>> >> >> Dear group: >>> I have a function that gets five arguments, two of which are fixed, and >>> three vary. Its output are three numbers. So it can be nested, for >>> example >>> over some initial values. >>> Say: >>> Nest[func[arg1,arg2,#[[1]],#[[2]],#[[3]]]&,{init1,init2,init3},k] >>> >>> Simple enough, works well. >>> Now I want to nest the same function, while the second non fixed argument >>> changes at each step. I thought the "natural" way of doing this was: >>> >>> >>> NestWhile[func[arg1,arg2,#[[1]],#[[2]],#[[3]]]&,{init1,init2,init3},UnsameQ[#[[2]]&,2], >>> but this evidently does not work. >>> >>> So: in a NestWhile how do I create tests over parts of the outputs of a >>> function? >>> Thanks! >>> Fg >>> >>> >>> > > -- > DrMajorBob(a)yahoo.com >
|
Pages: 1 Prev: Sorting paired columns of dates and values Next: Initialization problem in a |