On Wed, 02 Nov 2011 11:25:28 -0000, Francisco Gutierrez
<fgutiers2002 at yahoo.com> wrote:
> Dear Group:
>
> I have a function, and I iterate it using fixedpoint. Something of this
> sort:
>
> FixedPointList[
> function[arg1,arg2,arg3, #] &, arg4,
> SameTest -> (Max[Abs[Flatten[#1] - Flatten[#2]]] < 0.01 &)]
>
>
> I would like to know how many steps it takes this function to converge.
> I have tried with EvaluationMonitor to no avail:
>
> Block[{veamos, c = 0},
> veamos = FixedPoint[
> function[arg1,arg2,arg3, #] &, arg4,
> SameTest -> (Max[Abs[Flatten[#1] - Flatten[#2]]]< 0.01 &)];
> EvaluationMonitor :> c++; {veamos, c}]
>
>
> The iterator c simply does not move, and the previous function works ok
> but returns the value of c as 0.
>
> I tried if this was true with Length[FixedPointList[...]] and the answer
> was 20 (which should be the value of c in the immediately previous
> function). In principle, this would solve my problem, but it seems
> rather inefficient, especially when the convergence criterion is severe
> (not 0.01, but say 10^-4).
>
> Is there an efficient and nice way to solve this?
>
> Thanks,
>
> Francisco
FixedPoint doesn't accept the option EvaluationMonitor, so this approach
is a dead end. You could insert your counter into the SameTest; the number
of comparisons will be one more than the number required to achieve
convergence. However, I don't think this is likely to gain you very much;
Length at FixedPointList[...] will not incur a noticeable efficiency penalty
in most cases as building up a list of values is a fairly lightweight
operation. Another approach, of course, would be to use a While loop.
In regard to your SameTest: you may need to be careful with comparisons of
this sort where the absolute function values are large and the tolerance
is small since, due to the properties of floating-point numbers, the
relative error in this case may become arbitrarily small without the
absolute error necessarily falling below the value required for
convergence. Assuming that you're working in machine precision, you may be
better off using something along the lines of
SameTest -> (val = Max[Abs[Flatten[#1] - Flatten[#2]]]; val < tol +
val*Sqrt[$MachineEpsilon] &)
where tol is your chosen tolerance.