RE: Re: Manipulating Slot objects in Compile
- To: mathgroup at smc.vnet.net
- Subject: [mg24684] RE: [mg24604] Re: Manipulating Slot objects in Compile
- From: Wolf Hartmut <hwolf at debis.com>
- Date: Fri, 4 Aug 2000 01:19:07 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
my comment see below at [Hartmut Wolf] > -----Original Message----- > From: Jens-Peer Kuska [SMTP:kuska at informatik.uni-leipzig.de] To: mathgroup at smc.vnet.net > Sent: Friday, July 28, 2000 11:24 PM > To: mathgroup at smc.vnet.net > Subject: [mg24604] Re: Manipulating Slot objects in Compile > > Hi, > > can you tell me for what you need the Slot[] objects ? > You whant to generate cArg[[i]] and no Slot[1][[i]] > > The implementation is simple > f[{x_, y_}] := x^2 y^3 > arg = Table[Unique[], {2}]; > grad = Map[D[f[arg], #] &, arg]; > rules = Thread[ > arg -> Table[ > Hold[ cArg[[i]] ] /. i -> k, {k, 1, > 2}] ] > > and here is your function > > c = Compile @@ {{{cArg, _Real, 1}}, Hold @@ {grad /. rules}} /. > Hold[a_Part] :> a /. Hold[a_] :> Unevaluated[a] > > > I explained yesterday how it works. > > Regards > Jens > [Hartmut Wolf] Dear Johannes, I don't know what Jens explained yesterday, according to my observation, it does *not* work! What Jens did, was (1) compile the expression Hold @@ {grad /. rules} {2*Hold[cArg[[1]]]*Hold[cArg[[2]]]^3, 3*Hold[cArg[[1]]]^2*Hold[cArg[[2]]]^2} and (2) *then* manipulate the uncompiled function back to the intended (and correct) form. The compiled code however is useless, which you can suspect from c[[3]] {0, 0, 1, 0, 1} also, when you try Table[c[{x, y}][[1]], {x, 0, 1, 0.2}, {y, 0, 1, 0.2}] you'll see a host of error messages and finally General::"stop": "Further output of \!\(CompiledFunction :: \"cfex\"\) will \ be suppressed during this calculation." However, I think, things are much easier: observe, that you can differentiate "with respect to any expression that does not involve explicit mathematical operations" (S.Wolfram). Although I'm not shure what an "explicit mathematical operation" is (I guess something, that is affected by the rules of D -- unknown to us -- not of Derivative ???). Short, I presume Part[cArg,i] is none. So we can do: dimension = 2; Clear[cArg] Off[Part::"partd"] cArgList = Table[cArg[[i]], {i, dimension}] cc = Compile[{{cArg, _Real, 1}}, Evaluate[Map[D[f[cArgList], #] &, cArgList]]] cc[[3]] {0, 4, 11, 0, 2} g = MapThread[ ContourPlot[cc[{x, y}][[#1]], {x, 0, 1}, {y, 0, 1}, Contours -> 20, ContourShading -> False, ContourStyle -> Hue[#2], DisplayFunction -> Identity] &, {{1, 2}, {0, 2/3}}] Show[g, DisplayFunction -> $DisplayFunction] You'll see the contours you expected (with compiled code used). Kind regards, Hartmut > Johannes Ludsteck wrote: > > > > Dear Mathgroup Members, > > I want to write a program which computes the gradient of any > > function and then compiles this expression. I tried to do this by > > manipulating Slot objects. > > Unfortunately there is the following problem: > > First I define an example function. > > > > f[{x_, y_}] := x^2 y^3, > > > > Then I generate a list of (unique) variables for differentiation: > > > > arg = Table[Unique[], {2}] > > {$1,$2} > > and compute the gradient: > > > > grad = Map[D[f[arg], #] &, arg] > > {2 $1 $2^3, 3 $1^2 $2^2} > > > > Then I generate a set of replacement rules > > rules = Table[arg[[i]] -> Slot[][[i]], {i, 2}] > > > > and use them in order to get compiled code by > > applying r to grad > > > > c = Compile[{{cArg, _Real, 1}}, > > Evaluate[Evaluate[grad /. r] &[cArg]]] > > Unfortunately, Mathematica doesn't replace the Slot[] object by > > cArg and I get the following Output: > > > > CompiledFunction[{cArg}, > > ( { 2 Slot[][[1]] Slot[][[2]]^3, 3 Slot[][[1]]^2 Slot[][[2]]^2 } & > )[cArg], > > -CompiledCode-] > > > > Thus I tried to circumvent the problem by using Slot[1] instead: > > rules = Table[arg[[i]] -> Slot[][[i]], {i, 2}] > > > > Now the Slot[1] object disappeared, but Slot[1][[1]] was replaced > > by 1 and I got again the false result: > > > > c = Compile[{{cArg, _Real, 1}}, > > Evaluate[Evaluate[grad /. r] &[cArg]]] > > now evaluates to > > > > CompiledFunction[{cArg}, > > { 2 cArg[[2]]^3, 3 cArg[[2]]^2}, -CompiledCode-] > > > > The Problem here is that Slot[1][[1]] is replaced by 1. > > How can I force Mathematica to replace Slot[][[i]] by cArg[[i]] or > > to replace Slot[[1]][[1]] by cArg[[1]] instead, or is there any other > > way to get a compiled gradient from any function? > > > > Any suggestions? > > > > Of course, the seemingly awkward usage of Unique[] > > and Tables of rules is in order to collect the pieces of code into > > one Module which does the job for any function of any dimension > > (lenArg is the dimension of the argument list of function fun): > > > > compiledGradient[fun_, lenArg_] := > > Module[{arg, rules, grad}, > > arg = Table[Unique[], {lenArg}]; > > grad = Map[D[fun[arg], #] &, arg]; > > rules = Table[arg[[i]] -> Slot[][[i]], {i, lenArg}]; > > Compile[{{cArg, _Real, 1}}, > > Evaluate[Evaluate[grad /. rules] &[cArg]]]] > > > > Thank you and best regards, > > Johannes Ludsteck > > > > Johannes Ludsteck > > Centre for European Economic Research (ZEW) > > Department of Labour Economics, > > Human Resources and Social Policy > > Phone (+49)(0)621/1235-157 > > Fax (+49)(0)621/1235-225 > > > > P.O.Box 103443 > > D-68034 Mannheim > > GERMANY > > > > Email: ludsteck at zew.de