Message Boards Message Boards

0
|
9879 Views
|
4 Replies
|
1 Total Likes
View groups...
Share
Share this post:

[?] Use NestWhile using a function with 2 arguments one sets parameters?

Posted 7 years ago

I want to use

gf[x_, y_] := 
 Module[{x1, x2, xtst, fnw, f1, xnw}, xtst = Total[x]/2;fnw = 
   LAcr[xtst, 1/12., LAI, LBI, AF, a, b, c, d, 
    400000.,a, y];
  f1 = LAcr[x[[1]], 1/12., LAI, LBI, AF, a, b, c, d, 
    400000., a, y]];
  Return[If[Sign[fnw] == Sign[f1], {xtst, x[[2]]}, {x[[1]], xtst}]];]
as the input to 
NestWhile[
   gf, {500., 50000.}, #[[2]] - #[[1]] > 0.0001 &]

where the return parameters are {xlowerfinal,xupperfinal} are the final values of { #[[1]],#[[2]]} and the value of y is to be supplied before entering NestWhile by using the Table function to introduce a list of y values. Can one convert a a 2 variable (here x, y) function into a 1 variable function of x by automatically introducing the y values using Table? Or is there some way of making ListWhile know which variable (x) to use?

POSTED BY: Robert Curl
4 Replies

I apologize for not following the rules. The code for my actual problem using the hints by Bill Simpson follows. Unfortunately I seem to not be able to think of a simple example.

This is the solution to the problem I posted earlier today using the code for the actual problem. 
The functions and input paramaters are defined in another notebook.
gf\[Beta][{x_, \[Beta]_}] := 
 Module[{x1, x2, xtst, fnw, f1, xnw}, xtst = Total[x]/2; 
  fnw = LAcr[xtst, 1/12., LAI, LBI, AF, a, b, c, d, 
    400000., \[Alpha]0, \[Beta]]; 
  f1 = LAcr[x[[1]], 1/12., LAI, LBI, AF, a, b, c, d, 
    400000., \[Alpha]0, \[Beta]]; 
  Return[If[Sign[fnw] == Sign[f1], {xtst, x[[2]]}, {x[[1]], xtst}]];]
  f1 = LAcr[x[[1]], 1/12., LAI, LBI, AF, a, b, c, d, 
    400000., \[Alpha]0, \[Beta]]; 
  Return[If[Sign[fnw] == Sign[f1], {xtst, x[[2]]}, {x[[1]], xtst}]];]`
f[x_] := gf\[Beta][{x, .6}]
t works slightly differently from previously.  What used to work, doesn't.
In[27]:= NestWhile[f, {500., 50000.}, test &]

Out[27]= {500., 50000.}
However, if I add a large integer it does.
In[28]:= NestWhile[f, {500., 50000.}, test &, 100]

Out[28]= {35964.7, 35964.7}
The integer seems to be the number of iterations.`enter code here`
In[29]:= NestWhile[f, {500., 50000.}, test &, 3]

Out[29]= {25250., 37625.}
POSTED BY: Robert Curl

You have solved my problem. Thank you very much for your help! There is one peculiar feature that is no problem for me. If I use f[x_] := gf][{x, .5}], it works if I use NestWhile[f, {500., 50000.}, test &, 100], but it fails if I use NestWhile[f, {500., 50000.}, test &] , i.e. omit the last parameter, which I think is supposed to be the number of previous results available for use, it doesn't work. It just spits out the original input range. The peculiar thing is that if I make the original gf have only one parameter, i.e. set a value of y in the definition of gf and use gf as a function of one parameter, this extra parameter in NestWhile is not needed.

POSTED BY: Robert Curl
Posted 7 years ago

Usually the & is only used to indicate the end of an "anonymous" function that hasn't been previously defined. You can look up "Function" in the help pages and see what you can make of that. It is sometimes confusing for new users because they are several different notations used to accomplish the same thing and this can take a while to figure out.

It is also the case that it is sometimes difficult to figure out exactly what some fragment of Mathematica code might do, even if you are using it in a fairly conventional and expected way. That difficulty is magnified substantially if you start using something in an unconventional and unexpected way.

Mathematica provides the ability to Trace the execution of code using Trace[...your Mathematica expression...], but it may take a little experimenting to understand the output from Trace. If you can figure that out, perhaps starting with very simple examples and working your way up, then this might help you understand what is happening and what is going wrong in your actual code.

The fourth argument to NestWhile is described in the help pages, particularly if you click on the "Details" or sometimes labeled "Details and Options" near the top of the help page. When you think you understand NestWhile then you might try creating some very simple examples and explore whether it acts as you expect.

Beyond this I am at a disadvantage because I don't have a description of what you are really trying to accomplish and don't have a complete set of code to experiment with to check whether my suggestions even make sense.

I'm glad that what I wrote earlier gave you some assistance.

POSTED BY: Bill Simpson
Posted 7 years ago

A common trick to distinguish names when you have more than one # or more than one x is to introduce a named function.

So try changing your

NestWhile[ gf, {500., 50000.}, #[[2]] - #[[1]] > 0.0001 &]

to

test[p_] := p[[2]] - p[[1]] > 0.0001;
NestWhile[f, {500., 50000.}, test]

and now you could use a separate # inside your NestWhile without confusion.

Next the trick to get NestWhile to work with two arguments is to give it a list of two items instead of two individual items. Thus

gf[{x_, y_}]:=

instead of

gf[x_, y_]

and then modify your NestWhile arguments to match.

If you think about this a bit then it should give you enough of a hint that you can make this work.

POSTED BY: Bill Simpson
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract