3
$\begingroup$

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.

$\endgroup$
2
  • $\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, 2013 at 1:49
  • $\begingroup$ Related or possible duplicate: (7999) $\endgroup$
    – Mr.Wizard
    Aug 13, 2013 at 17:29

2 Answers 2

6
$\begingroup$

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

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

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}
$\endgroup$
1
  • $\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$ Aug 14, 2013 at 12:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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