MathGroup Archive 2006

[Date Index] [Thread Index] [Author Index]

Search the Archive

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/


  • Prev by Date: Re: Defining two functions at once?
  • Next by Date: Re: Defining two functions at once?
  • Previous by thread: Re: Defining two functions at once?
  • Next by thread: Re: Defining two functions at once?