Message Boards Message Boards

Integer inside [] is unexpectedly changed to a machine-precision real number

Posted 7 months ago

As shown below, I have written code to find the numerical solution of the equation for an arbitrary number of variables.

variableN = 3;
solveEquations[a_] := Module[
  {x}
  ,
  Table[x[i], {i, 0, variableN}] /. FindRoot[
    Catenate[
     {
      {x[0] == 1}
      , Table[x[i] == Gamma[a, x[i - 1]], {i, 1, variableN}]
      }
     ]
    , Table[{x[i], 1}, {i, 0, variableN}]
    ]
  ]

The calculations in the code are trivial, but the actual system I want to solve is much more complex.

Anyway, the code works fine for most inputs.

In[304]:= {solveEquations[1], solveEquations[2]}
Out[304]= {{1., 0.367879, 0.692201, 0.500474}, {1., 0.735759, 
  0.831674, 0.797364}}

However, errors are acquired for certain inputs.

In[3]:= solveEquations[1.]

During evaluation of In[3]:= FindRoot::nlnum: The function value {0.,1. -1. 2.71828^(-1. x$4490[0.]),1. -1. 2.71828^(-1. x$4490[1.]),1. -1. 2.71828^(-1. x$4490[2.])} is not a list of numbers with dimensions {4} at {x$4490[0],x$4490[1],x$4490[2],x$4490[3]} = {1.,1.,1.,1.}. 

(omitted)

Out[3]= {x$4490[0], x$4490[1], x$4490[2], x$4490[3]} /. 
 FindRoot[
  Catenate[{{x$4490[0] == 1}, 
    Table[x$4490[i] == Gamma[1., x$4490[i - 1]], {i, 1, variableN}]}],
   Table[{x$4490[i], 1}, {i, 0, variableN}]]

After investigating the cause, I found that if the first argument of the incomplete gamma function is 1. , the contents of [] in the second argument are also converted to real numbers.

In[6]:= {Gamma[2., x[0]], Gamma[1., x[0]]}
Out[6]= {Gamma[2., x[0]], E^-x[0.]}

The error occurs since x[0] and x[0.] are different.

Is this result inevitable? or is there any good solution?

Thanks,

POSTED BY: Aki Hiro
6 Replies
Posted 7 months ago

Sorry, I suddenly got busy and my reply was delayed.

I had never thought of a way to create temporary variables using Unique, but it seems like a good way. Although I'm not familiar with handling Context, I found that side effects can be cancelled by doing something like Remove["`MyPrivate`*"].

An advantage of my function notation is that zero or negative number "subscripts" are available, and this is the same with your proposed Subscript description.Additionally, it feels more natural and reasonable to use Subscript than function notation. It somehow doesn't be affected by N[]...

My question have been resolved, thank you!

POSTED BY: Aki Hiro
Posted 7 months ago

Gianluca's suggestion is nice, but to me the semantics of your code is still problematic. I'd probably do something like this:

solveEquations3[a_, varCount_] :=
 Module[
  {x, vars},
  vars = Table[x[i], {i, 0, variableN}];
  Values[
   FindRoot[
    Catenate[
     {{vars[[1]] == 1},
      Table[vars[[i]] == Gamma[a, vars[[i - 1]]], {i, 2, varCount}]}],
    Thread[{vars, 1}]]]]
POSTED BY: Eric Rimbey
Posted 7 months ago

I have made a slight modification to your code to make it work, but I still get the error output.

solveEquations3[a_, varCount_] := Module[
  {x, vars}
  ,
  vars = Table[x[i], {i, 0, varCount}];
  Values[
   FindRoot[
    Catenate[{{vars[[1]] == 1}, 
      Table[vars[[i]] == Gamma[a, vars[[i - 1]]], {i, 2, 
        varCount + 1}]}], Thread[{vars, 1}]]]]

solveEquations3[1., 3]

What problems do you see with Gianluca's solution?

POSTED BY: Aki Hiro
Posted 7 months ago

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.

POSTED BY: Updating Name

Try SetAttributes[x, NHoldFirst].

POSTED BY: Gianluca Gorni
Posted 7 months ago

Simple solution, Thank you!

POSTED BY: Aki Hiro
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract