MathGroup Archive 1999

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

Search the Archive

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



  • Prev by Date: Re: Strange ReplaceRepeated
  • Next by Date: Re: BesselJZeros problem/bug?
  • Previous by thread: List of function-heads
  • Next by thread: Re: List of function-heads