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.

  • $\begingroup$ 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. $\endgroup$ – rcollyer Aug 13 '13 at 1:49
  • $\begingroup$ Related or possible duplicate: (7999) $\endgroup$ – 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}

Mathematica graphics

  • 2
    $\begingroup$ Lena, oh Lena, please accept my apologies! $\endgroup$ – Dr. belisarius Aug 13 '13 at 3:29
  • $\begingroup$ Damn. Should have noticed that small issue. +1, grudgingly. :) $\endgroup$ – rcollyer Aug 13 '13 at 13:42
  • $\begingroup$ @rcollyer Ha! Mma always finds a way to get me staring stupidly at a line of code for hours $\endgroup$ – Dr. belisarius Aug 13 '13 at 13:56
  • $\begingroup$ 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. $\endgroup$ – rcollyer Aug 13 '13 at 14:09
  • $\begingroup$ This did it! Thank you! $\endgroup$ – 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).


  • 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:


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}
  • $\begingroup$ 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? $\endgroup$ – David Bruce Borenstein Aug 14 '13 at 12:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.