I am trying to represent the following function definition in Mathematica:
$$\begin{align*} f(1)&=1 \\ f(2n)&= \begin{cases}f(n) & \text{if}\space n\equiv0\pmod{2} \\ 2f(n) & \text{if}\space n\equiv1\pmod{2}\end{cases} \\ f(2n+1)&=\begin{cases}2f(n)+1 & \text{if}\space n\equiv0\pmod{2} \\ f(n) & \text{if}\space n\equiv1\pmod{2}\end{cases} \end{align*}$$
I have tried both the following definitions, but both of them return f[2011] as their output when I input f[2011] into the kernel.
Using if-statements:
f[1] := 1
f[2 n_] := If[Mod[n, 2] == 0, f[n], 2 f[n]]
f[2 n_ + 1] := If[Mod[n, 2] == 0, 2 f[n] + 1, f[n]]
And using switch-statements:
f[1] := 1
f[2 n_] := Switch[Mod[n, 2], 0, Evaluate[f[n]], 1, 2 Evaluate[f[n]]]
f[2 n_ + 1] := Switch[Mod[n, 2], 0, 2 Evaluate[f[n]] + 1, 1, Evaluate[f[n]]]
Neither of these definitions seem to give me what I'm after, so I'd appreciate any help.
Answer
I'd have done something like this:
f[1] = 1;
f[n_Integer?EvenQ] := f[n] =
Block[{m = n/2}, (1 + Boole[Mod[m, 2] == 1]) f[m]];
f[n_Integer?OddQ] := f[n] =
Block[{m = (n - 1)/2, t}, t = Boole[Mod[m, 2] == 0]; (1 + t) f[m] + t]
The use of both := and = in the odd and even cases is sometimes referred to as memoization; there are a number of threads on this site (e.g. the one just linked to) that discuss that in more detail.
In any event,
AbsoluteTiming[f[2011]]
{0.000785, 21}
If one wanted to compress things as with the other answers given,
f[1] = 1;
f[n_Integer] := f[n] =
Block[{m = Quotient[n, 2], t}, t = Mod[m, 2];
If[EvenQ[n], (1 + t) f[m], (2 - t) f[m] - t + 1]]
Comments
Post a Comment