2
$\begingroup$

I have a function which runs a sum from -integer to integer based on some data, something like, schematically

troublesomefunction[data_,limit_Integer]:=Sum[simplefunction[data,i],{i,-limit,limit}]

I know that troublesomefunction will eventually stay constant once limit is increased beyond a certain point. So I want a way to run troublesomefunction with limit=1, increase limit by one and run troublesomefunction again until I find the fixed point. I can't work out how to use FixedPoint for this, so is there a different function I should be using, or is there a way to apply fixed point to my problem?

As a slightly more solid example, consider

Series[Total[Table[Fibonacci[n] x^n, {n, 3}]]/Total[Table[LucasL[n] x^n, {n, 3}]], {x, 0, 5}]

As you change the value 3 in the sequences you will see that the coefficients in the resultant series vary, then become fixed. So say I want an accurate fifth order series, I want to find what order I need to know the sequences to. The actual function I'm working with is not this one, so an analytic solution would be complicated in general I think.

Thanks.

$\endgroup$
4
  • $\begingroup$ Can you provide a simplefunction that exhibits the behavior you describe? $\endgroup$
    – Mr.Wizard
    Jun 5, 2015 at 16:13
  • $\begingroup$ You wouldn't happen to know the asymptotic behavior of simplefunction, no? That would greatly help in picking out a cutoff point. Otherwise, you're stuck with using an appropriate While[] loop. $\endgroup$ Jun 5, 2015 at 16:14
  • $\begingroup$ Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory Tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. $\endgroup$
    – bbgodfrey
    Jun 5, 2015 at 16:23
  • $\begingroup$ Thanks for the comments. I've added a function that behaves in the way I was trying to describe. If you run the example function I gave and change the value of 3 that describes what order the sequences are calculated to you will see the coefficients of the series change. $\endgroup$
    – Se314en
    Jun 5, 2015 at 16:30

1 Answer 1

2
$\begingroup$

I shall use UnitBox roughly in place of your simplefunction for the sake of example. I shall leave out data but that doesn't really affect the methods that I would use. So we start with:

foo[limit_Integer] := Sum[UnitBox[i/20], {i, -limit, limit}]

FixedPoint is not directly written to handle this case. Attempting to do this without introducing additional Symbols we could put foo in the SameTest option and use a simple incrementer function like so:

FixedPoint[# + 1 &, 1, SameTest -> (foo[#] == foo[#2] &)]
11

But it is probably not the right way to handle this, notably it is going to apply foo twice to most limit values. You could get around that with memoization but why go to such trouble? It is easier to use Module and PreIncrement:

Module[{i},
 FixedPoint[foo[++i] &, i = 0];
 i
]
11

This is only using the FixedPoint for side-effects. We could also use ReplaceRepeated:

Module[{i = 0},
  0 //. _ :> foo[++i];
  i
]
11

Or as noted in the comments if you want the value of the output of the function returned rather than the limit value this simplifies to:

Module[{i = 0}, 0 //. _ :> foo[++i]]
21

I like this but I also realize it is probably confusing to people not intimate with Mathematica functions. Plain old procedural loops have their place and this may be one of them.

$\endgroup$
5
  • $\begingroup$ Yeah, summing an infinite series without any advance knowledge of where to cut it off is definitely an appropriate time for a loop. But if one insists on the procedure here, you could also use NestWhile[] instead of FixedPoint[]. $\endgroup$ Jun 5, 2015 at 16:42
  • $\begingroup$ Thanks for the answer. I have a couple of questions if that's ok? First, I want the result, not the limit, so it seems 'Module[{i}, FixedPoint[foo[++i] &, i = 0] ]' is what I need. But could you explain what I'm getting by putting this in a module instead of simply 'FixedPoint[foo[++i] &, i = 0]', which still seems to return 21? Is it simply well defined locality? $\endgroup$
    – Se314en
    Jun 5, 2015 at 16:47
  • $\begingroup$ Interesting to hear you both suggesting the use of a loop. I'm still new to learning mathematica obviously and I always got the feeling that loops weren't very 'mathematica-y'? $\endgroup$
    – Se314en
    Jun 5, 2015 at 16:52
  • 1
    $\begingroup$ @Se314en, the point of that advice you heard is that in most applications, stuff done procedurally is often more compactly and readably expressed in a functional manner, but there will always be situations where the functional way looks clunky compared to the procedural way. This looks like one of those cases, at least to me. $\endgroup$ Jun 5, 2015 at 17:04
  • $\begingroup$ @Se314en Yes, if you want the result instead of the value of i you can use Module[{i}, FixedPoint[foo[++i] &, i = 0] ]. I'll update my answer with this. The reason for Module is so that you do not leave a global assignment to i. For basic line-by-line input it may not matter but in my opinion it is good practice to use it. $\endgroup$
    – Mr.Wizard
    Jun 5, 2015 at 17:19

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.