# Writing a function that returns a (usable) function

I am trying to create a function that returns Arnold's Cat Map of size n iterated k times. I can get something out of the Function command, but I can't figure out how to use that output as a function.

The non-iterated version of the problem is trivial. I define my mapping function:

G[x_, y_, n_] := Mod[{{2, 1}, {1, 1}}.{x, y}, n];


I want it to work with ImageTransformation, so I define an appropriate function for that:

CatMapStep[{x_, y_}] := G[x, y, side];


where side is calculated somewhere earlier. Now I can call ImageTransformation (let's say I have an image kitty):

ImageTransformation[kitty, CatMapStep]


Done. But what do I do if you want to iterate CatMap k times? Well, I can hard-code k:

CatMapFiveTimes[u_] := Nest[CatMapStep[u], u, 5];


And I discovered the Function' command, but I can't figure out how to use it. What I would really like to do is create a function that takes k as an argument, and returns a function of u. Such is the sentiment of the following incorrect snippet:

IteratedCatMap[k_] := Function[u, Nest[CatMapStep[u], u, k];   <--- DOESN'T WORK


In my fantasy world, I would then be able to define CatMapFiveTimes by invoking the following line:

CatMapFiveTimes[u_] = IteratedCatMap[5];     <--- HYPOTHETICAL


And then using it as I would the previous definition.

How can I create this function that returns a function?

Thanks, David

PS: Note that I am using Mathematica 8, although my officemate has Mathematica 9 and she couldn't get it, either.

PPS: I am completely open to a totally different approach to this problem. Ultimately, my only goal is to use Manipulate to let my students specify how many iterations of the cat map they want to see. I will be doing similar things for the Mandelbrot set, as well.

-
Define "doesn't work." What happens when you run it? The reason I ask is I've run your code, and I've seen what happens. But, you don't give enough info for the casual reader to know what the issue is. – rcollyer Aug 13 '13 at 1:49
Related or possible duplicate: (7999) – Mr.Wizard Aug 13 '13 at 17:29

Perhaps just a syntax problem:

side = 1;
kitty = ExampleData[{"TestImage", "Lena"}];
G[x_, y_, n_] := Mod[{{2, 1}, {1, 1}}.{x, y}, n];
CatMapStep[{x_, y_}] := G[x, y, side];
CatMapFiveTimes[u_] := Nest[CatMapStep, u, 5];
it5 = ImageTransformation[kitty, CatMapFiveTimes];

IteratedCatMap[k_] := Function[u, Nest[CatMapStep, u, k]];
itt5 = ImageTransformation[kitty, IteratedCatMap[5]];

GraphicsRow@{it5, itt5}


-
Lena, oh Lena, please accept my apologies! – Dr. belisarius Aug 13 '13 at 3:29
Damn. Should have noticed that small issue. +1, grudgingly. :) – rcollyer Aug 13 '13 at 13:42
@rcollyer Ha! Mma always finds a way to get me staring stupidly at a line of code for hours – Dr. belisarius Aug 13 '13 at 13:56
I had a semi-colon issue once. A single misplaced semi-colon was fubaring about 500 lines of code, and I couldn't find the damn thing. Two syntax highlighters and Mr.Wizard's message tool later, I found it. But, it took much longer than I care to admit to. – rcollyer Aug 13 '13 at 14:09
This did it! Thank you! – David Bruce Borenstein Aug 14 '13 at 12:48

This question is related to and possibly a duplicate of: Define parameterized function

First there appears to be a mistake in your code; I believe you wanted:

CatMapFiveTimes[u_] := Nest[CatMapStep, u, 5]


To realize your IteratedCatMap we do not need to generate a function, merely to use a SubValues pattern definition (as discussed in the link above).

IteratedCatMap[n_][u_] := NestList[CatMapStep, u, n]


I have used NestList above in place of Nest simply to make the operation of the function visible.

With our supporting definitions in place:

G[x_, y_, n_] := Mod[{{2, 1}, {1, 1}}.{x, y}, n];
CatMapStep[{x_, y_}] := G[x, y, side];
side = Prime @ 50;


To use this you simply write:

IteratedCatMap[5][{62, 35}]

{{62, 35}, {159, 97}, {186, 27}, {170, 213}, {95, 154}, {115, 20}}  (* five + original *)


You can define your "function" like this:

CatMapThreeTimes = IteratedCatMap[3];

CatMapThreeTimes[{62, 35}]

{{62, 35}, {159, 97}, {186, 27}, {170, 213}} (* three + original *)


Note that the value of CatMapThreeTimes is not a function, it is simply a head waiting to be completed before the SubValues rule triggers.

You can use Function as also discussed in the linked question:

IteratedCatMapAlt[n_] := NestList[CatMapStep, #, n] &

CatMapTwoTimes = IteratedCatMapAlt[2];


The value of CatMapTwoTimes is a function (a pure function, specifically).

## Notes

• It is generally a good idea to avoid starting user Symbol names with capital letter, especially short or generic names like G because these may conflict with System Symbols now or in the future.

• Beware creating function that rely on a global definition such as side. It is often better to include such a parameter as an argument, possibly using SubValues as discussed above.

To illustrate the second point you might write your functions like this:

ClearAll["Global*"]

G[side_][{x_, y_}] := Mod[{{2, 1}, {1, 1}}.{x, y}, side]

catMap[side_, n_][u : {_, _}] := Nest[G[side], u, n]


You can then create a particular version of the "function" simply with:

catMap4 = catMap[229, 4];


And use it:

catMap4[{62, 35}]

{95, 154}
`
-
Thank you! So would this be more computationally efficient than the Nest approach, because the new function is not actually generated? I don't have a very good sense of how Mathematica evaluates things. The function was actually named \Gamma, but I couldn't paste the Greek letter, so I decided to change it to G. I will keep that in mind about the global parameters. Is there a book on Mathematica programming that's reasonably concise and informative? – David Bruce Borenstein Aug 14 '13 at 12:51