I'm currently learning Mathematica and was reading through some lecture notes which were trying to explain recursive functions, they then went on to give the following examples:
mapg[list_] := Prepend[ mapg[Rest[list]] , g[First[list]] ];
mapg[{}] := {};
mapg[{a, b, c}]
which gives the output: {g[a], g[b], g[c]}
While I understand the meaning of the individual functions (Prepend, Rest, First), I don't understand how this is a recursive function and how it actually works to give the output that it gives.
Another example given is:
primefactorial[1] := 1;
primefactorial[n_] := If[PrimeQ[n], n # , #] &@primefactorial[n - 1]
primefactorial /@ Range[23]
Which gives the output: {1, 2, 6, 6, 30, 30, 210, 210, 210, 210, 2310, 2310, 30030, 30030, 30030, 30030, 510510, 510510, 9699690, 9699690, 9699690, 9699690, 223092870}
Again, while I understand what the PrimeQ function does and the If function, I'm confused about what the actual recursive function is doing. In particular what does "n #" do in the If function? Also what does @primefactorial[n-1] do? What is being applied to primefactorial[n-1] exactly?
The first one
mapg[list_] := Prepend[ mapg[Rest[list]] , g[First[list]] ];
mapg[{}] := {};
mapg[{a, b, c}]
is just a way to write Map[g, list]
by prepending g[First[list]]
to mapg[Rest[list]]
. The key part here is that they've defined
mapg[{}] = {}
so that there's a concrete base case & you don't recurse infinitely. This works because
Rest[{a}] == {}
If you unwrap what's happening step-wise in that call you get
mapg[{a, b, c}] == Prepend[Prepend[Prepend[{}, c], b], a]
The second case is a bit more subtle, since they've used pure (anonymous) function notation. In this case they have
If[PrimeQ[n], n # , #] &@primefactorial[n - 1] ==
If[PrimeQ[n], n*primefactorial[n - 1], primefactorial[n - 1]]
which just says if n
is a prime number, then multiply it by the previous factorial expansion, otherwise do nothing and just return the previous expansion.
The recursion comes in the primefactorial[n - 1]
step, where again to prevent infinite recursion they've defined
primefactorial[1] = 1
You could symbolically expand this like
symbolicPrimeFactorial[1] := prime[1];
symbolicPrimeFactorial[n_] := If[PrimeQ[n], prime[n]*#, #] &@symbolicPrimeFactorial[n - 1]
symbolicPrimeFactorial /@ Range[1, 23, 2] // Column
prime[1]
prime[1] prime[2] prime[3]
prime[1] prime[2] prime[3] prime[5]
prime[1] prime[2] prime[3] prime[5] prime[7]
prime[1] prime[2] prime[3] prime[5] prime[7]
prime[1] prime[2] prime[3] prime[5] prime[7] prime[11]
prime[1] prime[2] prime[3] prime[5] prime[7] prime[11] prime[13]
prime[1] prime[2] prime[3] prime[5] prime[7] prime[11] prime[13]
prime[1] prime[2] prime[3] prime[5] prime[7] prime[11] prime[13] prime[17]
prime[1] prime[2] prime[3] prime[5] prime[7] prime[11] prime[13] prime[17] prime[19]
prime[1] prime[2] prime[3] prime[5] prime[7] prime[11] prime[13] prime[17] prime[19]
prime[1] prime[2] prime[3] prime[5] prime[7] prime[11] prime[13] prime[17] prime[19] prime[23]
and hopefully this is pretty clear as to what's going on