6

@Валерий Заподовников remarks:

BTW, it is also quite bad that Mathematica does not have Bertrand test.

Is there a way to extend the convergence tests in SumConvergence[] with user-defined methods?

In the linked Q&A, the series whose convergence is in question is given in the following command, which returns unevaluated:

SumConvergence[1 - Cos[Pi/n], n]

@Валерий points out that Bertand's test works on this series. Is there a way to apply Bertrand's test or any other test on this series?

Michael E2
  • 235,386
  • 17
  • 334
  • 747

1 Answers1

9

Yes, you can pass a function of the form usermethod[expr, k] to Method, although I cannot find any documentation for it:

Sum[expr, k, Method -> usermethod]

The specification usermethod should be a Symbol or a string. A non-string is passed through ToExpression[ToString[usermethod]], so if it is a non-symbol expression, it needs to make the round-trip unaltered. A good way to do this is to use SetOptions on ToString to set FormatType -> InputForm. A string value for usermethod is passed directly through ToExpression and putting string quotes around a complicated expression for usermethod can be an easier way than SetOptions. See multitest, lct and the Update below for examples.

The return values are handled thus:

Result Meaning
True Converges
False Diverges
$Failed Indeterminate; SumConvergence unevaluated
unevaluated Indeterminate; SumConvergence unevaluated
Garbage Garbage

An example of garbage:

foo[expr_, k_] := Umm ...;
SumConvergence[1 - Cos[Pi/n], n, Method -> foo]
(*  Umm ...  *)

It is as though the test is treated as successful and the user-defined return value is assumed to have some meaning for the user.

Example: Bertrand's test

bertrand[expr_, k_] := Module[{ratio, res},
   ratio = Together[(expr /. k -> k + 1)/expr];
   res = Limit[Log[k] (k (1/ratio - 1) - 1), k -> Infinity];
   res > 1 /; FreeQ[res, Limit | Indeterminate] && res != 1
   ];

SumConvergence[1 - Cos[Pi/n], n, Method -> bertrand]

(* True *)

The Automatic method is unsuccessful:

SumConvergence[1 - Cos[Pi/n], n, Method -> Automatic]

(* SumConvergence[1 - Cos[π/n], n, Method -> Automatic] *)

Example: Multiple tests

Unfortunately, one cannot specify a list of methods for SumConvergence[] to try (even though Automatic tries many, many tests).

multitest // ClearAll;
multitest[tests_List][expr_, k_] :=
  Catch[
   With[{res = SumConvergence[expr, k, Method -> #]},
      If[FreeQ[res, SumConvergence], Throw@res]] & /@ tests;
   $Failed];

SumConvergence[1 - Cos[Pi/n], n, Method -> "multitest[{Automatic, bertrand}]"]

(* True *)

One limitation on multitest is that the methods in tests are passed through ToExpression/ToString twice. Since these are not strictly inverse operations, some things are difficult to manage (see below).

Example: Limit Comparison Test

lct // ClearAll;
lct[expr2_][expr_, k_] :=
  Module[{res2, res1, res},
   res2 = SumConvergence[Abs@expr2, k];
   (res1 = Limit[Abs[expr/expr2], k -> Infinity];
     res = $Failed;
     If[res2 && TrueQ[0 <= res1 < Infinity],
      res = True,
      If[! res2 && TrueQ[0 < res1 <= Infinity],
       res = False]];
     res
     ) /; MatchQ[res2, True | False]
   ];

SumConvergence[1 - Cos[Pi/n], n, Method -> "lct[1/n^2]"]

(* True *)

Limitations

The following fails, because ToExpression is called twice:

SumConvergence[1 - Cos[Pi/n], n, 
 Method -> multitest[{"lct[1/n]", "lct[1/n^2]"}]]

Here's how the second lct gets clobbered:

ToExpression@ToString@ToExpression@"lct[1/n^2]"

(* lct[n] *)

By the way, ToString[expr, InputForm] is more reliable....

Update: Fix to the limitations

Finally remembering the obvious, I checked the docs on ToString, and a workaround stared me in the face: There's an option one set to get ToString to use InputForm:

Internal`InheritedBlock[{ToString},
 SetOptions[ToString, FormatType -> InputForm];
 SumConvergence[1 - Cos[Pi/n], n, 
  Method -> multitest[{lct[1/n], lct[1/n^2]}]]]

(* True *)

Michael E2
  • 235,386
  • 17
  • 334
  • 747