Re: Defining two functions at once?
- To: mathgroup at smc.vnet.net
- Subject: [mg70752] Re: [mg70730] Defining two functions at once?
- From: "Chris Chiasson" <chris at chiasson.name>
- Date: Thu, 26 Oct 2006 02:38:46 -0400 (EDT)
- References: <200610250539.BAA28821@smc.vnet.net>
The shape difference is due to the HoldAll attribute of SetDelayed. The right hand side is not evaluated until a pattern that matches the left hand side is encountered. Also, the first definition you gave will execute a "full" FindRoot (starting from f1->0 and g ->0) every time you call it; I don't know if you wanted that or not. Maybe you did, because I think I remember a time you were looking for the numeric solution of some equation over a small interval - and when I suggested homotopic extension, you said you weren't worried about the answer jumping to a different solution branch (and this probably means you weren't worried about performance, either). The second requirement, b, you gave for the solution seems rather odd, given that a call to a function like FindRoot probably involves executing many CompoundExpressions. However, I have learned my lesson and will attempt to give you exactly for what you asked. The definitions below only contain one CompundExpression and only evaluate FindMinimum as often as your original definition for the single f. In[1]:= defineFG[x_,y_]:= Block[{f1,g1}, defineFG[x, y]={f1,g1}/.FindRoot[{f1-g1\[Equal]x+3y,f1+g1\[Equal]2x-7y},{f1, 0},{g1,0}]];f[x_,y_]:=defineFG[x,y][[1]]; g[x_,y_]:=defineFG[x,y][[2]]; In[2]:= f[0.1,0.1]//Trace Out[2]= {f[0.1,0.1], defineFG[0.1,0.1]\[LeftDoubleBracket]1\[RightDoubleBracket],{defineFG[0.1, 0.1],Block[{f1,g1}, defineFG[0.1, 0.1]={f1, g1}/.\[InvisibleSpace]FindRoot[{f1- g1\[Equal]0.1\[InvisibleSpace]+3 0.1, f1+g1\[Equal]2 0.1-7 0.1},{f1,0},{g1, 0}]],{{{FindRoot[{f1-g1\[Equal]0.1\[InvisibleSpace]+3 0.1, f1+g1\[Equal]2 0.1-7 0.1},{f1,0},{g1, 0}],{{{{3 0.1,0.3},0.1\[InvisibleSpace]+0.3,0.4}, f1-g1\[Equal]0.4},{{{2 0.1,0.2},{{7 0.1,0.7},-0.7,-0.7}, 0.2\[InvisibleSpace]-0.7,-0.5}, f1+g1\[Equal]-0.5},{f1-g1\[Equal]0.4, f1+g1\[Equal]-0.5}},{{f1,g1}=.,{f1=.,g1=.},{f1=.,Null},{g1=., Null},{Null,Null}},{f1=.,Null},{g1=.,Null},{f1\[Rule]-0.05, g1\[Rule]-0.45}},{f1,g1}/.\[InvisibleSpace]{f1\[Rule]-0.05, g1\[Rule]-0.45},{-0.05,-0.45}}, defineFG[0.1, 0.1]={-0.05,-0.45},{-0.05,-0.45}},{-0.05,-0.45}},{-0.05,-0.45}\ \[LeftDoubleBracket]1\[RightDoubleBracket],-0.05} In[3]:= g[0.1,0.1]//Trace Out[3]= {g[0.1,0.1], defineFG[0.1,0.1]\[LeftDoubleBracket]2\[RightDoubleBracket],{defineFG[0.1, 0.1],{-0.05,-0.45}},{-0.05,-0.45}\[LeftDoubleBracket]2\ \[RightDoubleBracket],-0.45} On 10/25/06, AES <siegman at stanford.edu> wrote: > I want to define two functions at once, where both of their values > depend on the same two variables, and both of their values come out of a > single two-dimensional FindRoot which I'd rather not evaluate twice. > > The following approach seems to work fine for a *single* function > > f[x_, y_] := Module[{}, > myEqns = {f1 - g1 == x1 + 3y1, f1 + g1 == 2x1 - 7y1}; > myValues = {x1 -> x, y1 -> y}; > mySolns = FindRoot[ myEqns /. myValues, {f1, 0} , {g1, 0}]; > f1 /. mySolns] > > But if I try to define two functions at once by replacing the first and > last lines with > > {f[x_, y_], g[x_,y_]} := Module[{}, > myEqns = {f1 - g1 == x1 + 3y1, f1 + g1 == 2x1 - 7y1}; > myValues = {x1 -> x, y1 -> y}; > mySolns = FindRoot[ myEqns /. myValues, {f1, 0} , {g1, 0}]; > {f1, g1} /. mySolns] > > I get a message about "shapes not being the same". In fact, if I just > make the first and last lines even a single element list, e.g. > > {f[x_, y_]} := Module[{}, > myEqns = {f1 - g1 == x1 + 3y1, f1 + g1 == 2x1 - 7y1}; > myValues = {x1 -> x, y1 -> y}; > mySolns = FindRoot[ myEqns /. myValues, {f1, 0} , {g1, 0}]; > {f1} /. mySolns] > > this doesn't work either. > > If a module supposedly returns the result of its (compound) expression, > and the final term in that expression is a list, shouldn't the final > example work? More important (to me anyway): Is there a simple way to > define two functions that use a shared FindRoot evaluation in a way that > (a) evaluates the FindRoot only once, and (b) involves only a single > compound expression of some sort? > > -- http://chris.chiasson.name/
- References:
- Defining two functions at once?
- From: AES <siegman@stanford.edu>
- Defining two functions at once?