Re: List of function-heads
- To: mathgroup at smc.vnet.net
- Subject: [mg17094] Re: [mg17068] List of function-heads
- From: "Wolf, Hartmut" <hwolf at debis.com>
- Date: Sat, 17 Apr 1999 03:34:59 -0400
- Organization: debis Systemhaus
- References: <199904140612.CAA21186@smc.vnet.net.>
- Sender: owner-wri-mathgroup at wolfram.com
Hallo Peter, Peter Breitfeld schrieb: > > I want to create a List of function-heads like this: > {a[1][x_],a[2][x_],...,a[n][x_]} > (to keep this message short I'll use n=2 in the following) to assign > these to a list of Functions, e.g > > {a[1][x_],a[2][x_]}={x^2,x-1} > > I can do that with the following command: > > In[1]:=fl=Table[a[i][x_],{i,2}] > Out[1]={{a[1][x_],a[2][x_]} > > But then I can't write: > > ll={x^2,x-1} > > because now the a[i] are overwritten and not assosiated with the > elements of the rhs. > > Is there a way to get it working? I tried Thread, MapThread and some > more but didn't find a solution. > There are many possibilities: In[1]:= Clear[a,x] In[2]:= templates=Through[Array[a,4][x_]] Out[2]= {a[1][x_],a[2][x_],a[3][x_],a[4][x_]} In[3]:= bodies=Table[x^n,{n,1,4}] Out[3]= {x, x^2, x^3, x^4} Most straightforward seems to be threading Set through both lists. But beware of the attributes! In[4]:= Attributes[Set] Out[4]= {HoldFirst,Protected,SequenceHold} So you have to be careful with the first argument: In[5]:= Thread[Set[Evaluate[templates],bodies]] Out[5]= {x, x^2, x^3, x^4} In[6]:= ?a "Global`a" a[1][x_] = x a[2][x_] = x^2 a[3][x_] = x^3 a[4][x_] = x^4 In[7]:= a[4][4] Out[7]= 256 For SetDelayed you have to be very careful: In[8]:= Clear[a] In[9]:= Attributes[SetDelayed] Out[9]= {HoldAll,Protected,SequenceHold} In[10]:= Thread[SetDelayed[Evaluate[templates],Evaluate[bodies]]] Out[10]= {Null,Null,Null,Null} In[11]:= ?a "Global`a" a[1][x_] := x a[2][x_] := x^2 a[3][x_] := x^3 a[4][x_] := x^4 In[12]:= a[3][3] Out[12]= 27 Of course this makes nearly no sense, since you have to evaluate bodies to get at the list to be threaded, but SetDelayed is intended to be supplied with an unevaluated rhs. I don't know a way to evaluate bodies without evaluating its elements. So for this case you should prepare bodies with held elements: In[13]:= x=99999 Out[13]= 99999 In[14]:= heldBodies=Table[Hold[x]^i,{i,1,4}] Out[14]= {Hold[x], Hold[x]^2, Hold[x]^3, Hold[x]^4} In[15]:= Clear[a] In[16]:= Thread[Hold[SetDelayed][templates,heldBodies]] Out[16]= {Hold[SetDelayed][a[1][x_], Hold[x]], Hold[SetDelayed][a[2][x_], Hold[x]^2], Hold[SetDelayed][a[3][x_], Hold[x]^3], Hold[SetDelayed][a[4][x_], Hold[x]^4]} Now you don't need Evaluate any more, since you don't thread SetDelayed but Hold[SetDelayed] which evaluates its arguments (think a moment about that!) In[17]:= %//ReleaseHold Out[17]= {Null,Null,Null,Null} In[18]:= ?a "Global`a" a[1][x_] := x a[2][x_] := x^2 a[3][x_] := x^3 a[4][x_] := x^4 In[19]:= a[2][2] Out[19]= 4 In[20]:= x Out[20]= 99999 As to other possibilities, of course MapThread works in an analogous fashion. Also you could Thread, MapThread any symbol (say k) having no hold-attributes over templates and bodies and then slash-dot the result with k->Set or k->SetDelayed. However the crucial point is "was soll's?", aren't there much simpler methods to achieve your goal? See: In[21]:= Clear[a] In[22]:= ((a[#][x_]:=x^# )&) /@ Range[4] Out[22]= {Null,Null,Null,Null} In[23]:= ?a "Global`a" a[1][x_] := x^1 a[2][x_] := x^2 a[3][x_] := x^3 a[4][x_] := x^4 In[24]:= x Out[24]= 99999 This is a general design pattern to move (evaluated) numbers into something not evaluated. Note that the inner parentheses are essential! (try out without'em) You can do the same trick with held expressions too, e.g.: In[25]:= Clear[a] In[26]:= Hold[a[#][x_]:=x^# ]& /@ Range[4]//ReleaseHold Out[26]= {Null,Null,Null,Null} In[27]:= ?a "Global`a" a[1][x_] := x^1 a[2][x_] := x^2 a[3][x_] := x^3 a[4][x_] := x^4 In[28]:= x Out[28]= 99999 Finally pretty old Do is reluctant In[29]:= Clear[a] In[30]:= Do[a[i][x_]:=x^i ,{i,1,4}] In[31]:= ?a "Global`a" a[1][x_] := x^i a[2][x_] := x^i a[3][x_] := x^i a[4][x_] := x^i The index at the rhs is not evaluated! And evaluating the rhs will move the spurious value of x into the definition. But again a little trick helps: In[32]:= Clear[a] In[33]:= Do[With[{j=i},a[j][x_]:=x^j] ,{i,1,4}] In[34]:= ?a "Global`a" a[1][x$_] := x$^1 a[2][x$_] := x$^2 a[3][x$_] := x$^3 a[4][x$_] := x$^4 In[35]:= {a[1][1],a[2][2],a[3][3],a[4][4]} Out[35]= {1,4,27,256} In[36]:= x Out[36]= 99999 Looks queer, but With is essential here, since it moves the evaluated i into the rhs of SetDelayed! Also With renames our paramater variable, which is all right here! Hartmut Wolf
- References:
- List of function-heads
- From: phbrf@t-online.de (Peter Breitfeld)
- List of function-heads