RE: Defining function in loop
- To: mathgroup at smc.vnet.net
- Subject: [mg40427] RE: [mg40412] Defining function in loop
- From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
- Date: Sat, 5 Apr 2003 03:57:45 -0500 (EST)
- Sender: owner-wri-mathgroup at wolfram.com
>-----Original Message----- >From: vnagornyi at netscape.net [mailto:vnagornyi at netscape.net] To: mathgroup at smc.vnet.net >Sent: Friday, April 04, 2003 8:27 AM >To: mathgroup at smc.vnet.net >Subject: [mg40427] [mg40412] Defining function in loop > > >Hello, >I am definihg step-like function > >Clear[h] >h[x_] := 0/;x<0 >h[x_] := 1/;0<=x<=1 >h[x_] := 2/;1<=x<=2 >h[x_] := 3/;2<=x<=3 >h[x_] := 4/;x>3 > >It works fine: > >Table[h[x],{x,-1,4,.5}] >{0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4} > >As I may need more steps, I am trying to do the same in loop: > >Clear[g] >g[x_] := 0/;x<0 >Do[g[x_] := i/;i-1<=x<=i, {i,3}] >g[x_] := 4/;x>3 > >This time no luck: > >Table[g[x],{x,-1,4,.5}] >{0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4} >{0, 0, g[0.], g[0.5], g[1.], g[1.5], g[2.], g[2.5], g[3.], 4, 4} > >How to do this? > >Thanks. >Vadim. > Vadim, regard the result of yout attempted definition: In[12]:= ?g Global`g g[x_] := 0 /; x < 0 g[x_] := i /; i - 1 <= x <= i g[x_] := 4 /; x > 3 as you see the running varable i has not been evaluated at the rhs of set delayed! A logical step would be to force evaluation: In[15]:= x = Nonsense Out[15]= Nonsense In[16]:= Clear[g] g[x_] := 0 /; x < 0 Do[g[x_] := Evaluate[i /; Evaluate[i - 1 <= Unevaluated[x] <= i]], {i, 3}] g[x_] := 4 /; x > 3 In[21]:= Table[g[x], {x, -1, 4, .5}] Out[21]= {0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4} Simply Evaluate at rhs would not do since Condition has the HoldAll attribute, so we have to wrap Evaluate at the rhs of Condition. Now as Condition will be evaluated, the result now is the condition with evaluated lhs and rhs with i put in (and the arithmetic done). To protect x from an accidential value ("Nonsense" in our case, we wrap it with Unevaluated). To my surprise this wrapper isn't stripped here, but is later, when the definition is executed. So this works. Alternatively we might have tried to use Set instead of SetDelayed, but, alas, then we must attach the Condition to the lhs, such we have similar work: In[22]:= Clear[g] g[x_] := 0 /; x < 0 Do[Evaluate[g[x_] /; Evaluate[i - 1 <= Unevaluated[x] <= i]] = i, {i, 3}] g[x_] := 4 /; x > 3 In[27]:= Table[g[x], {x, -1, 4, .5}] Out[27]= {0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4} The recommended way however is different: substitute i into the expression, before it is evaluated: In[28]:= Clear[g] In[29]:= g[x_] := 0 /; x < 0 Do[With[{i = i}, g[x_] := i /; i - 1 <= x <= i], {i, 3}] g[x_] := 4 /; x > 3 In[33]:= Table[g[x], {x, -1, 4, .5}] Out[33]= {0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4} Or In[34]:= Clear[g] In[35]:= g[x_] := 0 /; x < 0 Scan[(g[x_] := # /; # - 1 <= x <= #) &, Range[3]] g[x_] := 4 /; x > 3 In[39]:= Table[g[x], {x, -1, 4, .5}] Out[39]= {0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4} Or In[94]:= Clear[g] In[95]:= g[x_] := 0 /; x < 0 Do[Unevaluated[g[x_] := i /; i - 1 <= x <= i] /. HoldPattern[i] -> i, {i, 3}] g[x_] := 4 /; x > 3 In[99]:= Table[g[x], {x, -1, 4, .5}] Out[99]= {0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4} -- Hartmut Wolf