From 429185051a0b9f0b6bfae7c6dfee49874a08bd87 Mon Sep 17 00:00:00 2001 From: Pablo Emilio Escobar Gaviria Date: Sat, 26 Sep 2020 15:10:17 -0300 Subject: [PATCH 1/5] Implemented the DiscreteLimit builtin --- mathics/builtin/calculus.py | 63 ++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/mathics/builtin/calculus.py b/mathics/builtin/calculus.py index 975e5a70ed..1ee91f2123 100644 --- a/mathics/builtin/calculus.py +++ b/mathics/builtin/calculus.py @@ -12,7 +12,7 @@ from mathics.core.rules import Pattern from mathics.core.numbers import dps from mathics.builtin.scoping import dynamic_scoping -from mathics import Symbol +from mathics import Symbol, String import sympy @@ -962,6 +962,67 @@ def apply(self, expr, x, x0, evaluation, options={}): return from_sympy(result) +class DiscreteLimit(Builtin): + """ +
+
'DiscreteLimit[$f$, $k$->Infinity]' +
gives the limit of the sequence $f$ as $k$ tends to infinity. +
+ + >> DiscreteLimit[n/(n + 1), n -> Infinity] + = 1 + + >> DiscreteLimit[f[n], n -> Infinity] + = f[Infinity] + """ + + # TODO: Make this work + """ + >> DiscreteLimit[(n/(n + 2)) E^(-m/(m + 1)), {m -> Infinity, n -> Infinity}] + = 1 / E + """ + + attributes = ('Listable',) + + options = { + 'PerformanceGoal': '"Quality"', + } + + messages = { + 'lperf': "Value of PerformanceGoal -> `1` should be \"Quality\" or \"Speed\".", + } + + def apply(self, f, n, n0, evaluation, options={}): + 'DiscreteLimit[f_, n_->n0_, OptionsPattern[DiscreteLimit]]' + + f = f.to_sympy(convert_all_global_functions=True) + n = n.to_sympy() + n0 = n0.to_sympy() + + if n0 != sympy.oo: + return + + if f is None or n is None: + return + + perf_goal = options['System`PerformanceGoal'].to_python() + if perf_goal == '"Quality"': + trials = 50 + elif perf_goal == '"Speed"': + trials = 5 + else: + evaluation.message('DiscreteLimit', + 'lperf', + options['System`PerformanceGoal']) + trials = 50 + + try: + return from_sympy(sympy.limit_seq(f, n, trials)) + except: + pass + + + class FindRoot(Builtin): r"""
From 79af956b8a1cd9e401549e2562f9ba8ba05d0ab1 Mon Sep 17 00:00:00 2001 From: Pablo Emilio Escobar Gaviria Date: Sat, 26 Sep 2020 15:12:07 -0300 Subject: [PATCH 2/5] Removed unnecessary import --- mathics/builtin/calculus.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mathics/builtin/calculus.py b/mathics/builtin/calculus.py index 1ee91f2123..04996f2e3a 100644 --- a/mathics/builtin/calculus.py +++ b/mathics/builtin/calculus.py @@ -12,7 +12,7 @@ from mathics.core.rules import Pattern from mathics.core.numbers import dps from mathics.builtin.scoping import dynamic_scoping -from mathics import Symbol, String +from mathics import Symbol import sympy From 5f680344e45cf4c3ec8ba7b0592a862e927ae9e2 Mon Sep 17 00:00:00 2001 From: Pablo Emilio Escobar Gaviria Date: Sat, 26 Sep 2020 15:52:26 -0300 Subject: [PATCH 3/5] Updated CHANGES.rst --- CHANGES.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.rst b/CHANGES.rst index c06a56d233..19cb43ad9d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,6 +12,7 @@ Major package dependencies ave been up dated to more recent releases. These incl New features: +- ``DiscreteLimit`` - ``IterationLimit`` - support for ``MATHICS_MAX_RECURSION_DEPTH`` - ``RemoveDiacritics[]``, ``Transliterate[]`` #617 From 84b3672e1a032af8437387cb45128d9135cdfb8a Mon Sep 17 00:00:00 2001 From: Pablo Emilio Escobar Gaviria Date: Mon, 28 Sep 2020 09:09:45 -0300 Subject: [PATCH 4/5] Replace the PerformanceGoal option with the more direct Trials option --- mathics/builtin/calculus.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/mathics/builtin/calculus.py b/mathics/builtin/calculus.py index 04996f2e3a..cbc7fc3266 100644 --- a/mathics/builtin/calculus.py +++ b/mathics/builtin/calculus.py @@ -985,11 +985,11 @@ class DiscreteLimit(Builtin): attributes = ('Listable',) options = { - 'PerformanceGoal': '"Quality"', + 'Trials': '5', } messages = { - 'lperf': "Value of PerformanceGoal -> `1` should be \"Quality\" or \"Speed\".", + 'dltrials': "The value of Trials should be a positive integer", } def apply(self, f, n, n0, evaluation, options={}): @@ -1005,16 +1005,11 @@ def apply(self, f, n, n0, evaluation, options={}): if f is None or n is None: return - perf_goal = options['System`PerformanceGoal'].to_python() - if perf_goal == '"Quality"': - trials = 50 - elif perf_goal == '"Speed"': + trials = options['System`Trials'].get_int_value() + + if trials is None or trials <= 0: + evaluation.message('DiscreteLimit', 'dltrials') trials = 5 - else: - evaluation.message('DiscreteLimit', - 'lperf', - options['System`PerformanceGoal']) - trials = 50 try: return from_sympy(sympy.limit_seq(f, n, trials)) From d376073f0142f9a818158c7bdd32dfea2417a8c6 Mon Sep 17 00:00:00 2001 From: Pablo Emilio Escobar Gaviria Date: Mon, 28 Sep 2020 09:30:19 -0300 Subject: [PATCH 5/5] Updated CHANGES.rst --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 19cb43ad9d..cfba5d1a68 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,7 +12,7 @@ Major package dependencies ave been up dated to more recent releases. These incl New features: -- ``DiscreteLimit`` +- ``DiscreteLimit`` #922 - ``IterationLimit`` - support for ``MATHICS_MAX_RECURSION_DEPTH`` - ``RemoveDiacritics[]``, ``Transliterate[]`` #617