Aaack! I'm so sorry and embarrassed. I posted an intermediate attempt instead of my intended solution. Let me try again, but first I'll respond to your question about my objections to Gianluca's solution. I'm uncomfortable with that solution on two levels. On the semantic level, it just keeps making these formal, throw-away symbols behave more like functions. While it's certainly not a perfect analogy to mathematical functions, an expression like x[1]
is generally interpreted as apply a function x
to the argument 1
. But all you need are formal variables. On the mechanistic level, an expression like x[1]
triggers the evaluation engine to go looking at DownValues
and thereby following a bunch of evaluation rules. Gianluca's solution is basically overriding the default rules to get the desired behavior. It's clever and it works, but it's just adding another layer of complication. As I've already said, we just need formal variables, we don't need down-value computation rules (aka function evaluation).
So, I'd probably do something like this:
solveEquationsNew[a_, varCount_] :=
With[
{vars = Table[Unique[x], varCount]},
Values[
FindRoot[
Catenate[{{vars[[1]] == 1}, Table[vars[[i]] == Gamma[a, vars[[i - 1]]], {i, 2, varCount}]}],
Thread[{vars, 1}]]]]
Now, this will add a bunch of unnecessary symbols into the Global context. If that's a problem, you could use special purpose contexts (e.g. Unique[
`MyPrivate`
x]
so you could clean up later (with Remove). Or you could try something like this:
solveEquationsNew[a_, varCount_] :=
Values[
FindRoot[
Catenate[{{Subscript[x, 1] == 1}, Table[Subscript[x, i] == Gamma[a, Subscript[x, i - 1]], {i, 2, varCount}]}],
Thread[{Table[Subscript[x, i], {i, varCount}], 1}]]]
There are many problems with using Subscript for formal variables, not the least of which is that you can assign down-values to Subscript. So, you might want to "localize" the x like this:
solveEquationsNew[a_, varCount_] :=
Module[
{x},
Values[
FindRoot[
Catenate[{{Subscript[x, 1] == 1}, Table[Subscript[x, i] == Gamma[a, Subscript[x, i - 1]], {i, 2, varCount}]}],
Thread[{Table[Subscript[x, i], {i, varCount}], 1}]]]]
This encapsulates the Subscript expressions and mitigates the problems with it. But using Subscript is basically the same idea as Gianluca's, because it relies on special attributes of Subscript.
I'm sure we could find several other ways to do this. It all depends on where your program needs to be robust, how much of a stickler you are for semantic purity, and your personal code aesthetic.