import dependent_bterms as dbt
%display typeset
AsymptoticRing
¶See the documentation of SageMath's module on asymptotic expansions for a primer on the AsymptoticRing
.
Assume that we want to carry out computations in a setting where we have a variable $n\to\infty$, as well as a dependent variable $k = k(n)$ for which we know $n^{\alpha} \leq k \leq n^{\beta}$ for some $0\leq\alpha\leq\beta$. Concretely, let us consider $1 = n^0 \leq k\leq n^{4/7}$.
Note: This implementation currently only supports monomial asymptotic growth of the independent variable. Trying to use it with more intricate growth groups other than $n^{\mathbb{Q}}$ will likely result in unwanted behavior.
AR, n, k = dbt.AsymptoticRingWithDependentVariable(
"n^QQ", "k", 0, 4 / 7, bterm_round_to=3, default_prec=5
)
Technically, k
is a plain symbolic variable -- the instantiated Asymptotic Ring uses the Symbolic Ring as its coefficient ring:
AR
k in SR
Arithmetic with the expansions from our special Asymptotic Rign works as usual:
(1 + 3 * n) * (4 * n ^ (-7 / 3) + 42 / n + 1)
prod((1 + n ^ (-j)) for j in srange(1, 10)) * (1 + O(n ^ (-10)))
n / (n - 1)
We can also simply use the dependent variable.
expr = k * n ^ 2 + O(n ^ (3 / 2)) + k ^ 3 * n
expr
Notice that the term order is now constructed with respect to the highest potential growth of a summand (i.e., if $k = k(n)$ were to assume its upper bound). We can ask the summands to reveal their respective growth bounds; the following tuples describe the lower and the upper bound of a summand, respectively:
for summand in expr.summands.elements_topological():
print(f"{summand} -> {summand.dependent_growth_range()}")
O(n^(3/2)) -> (n^(3/2), n^(3/2)) k*n^2 -> (n^2, n^(18/7)) k^3*n -> (n, n^(19/7))
Automatic expansions work too:
auto_expansion = exp((1 + k) / n)
auto_expansion
Note that the error term, $O(n^{-15/7})$, would be able to absorb some parts of the exact terms, after expanding the powers of $(k+1)$. This is not done automatically, but can easily be triggered via a utility function from our toolbox:
dbt.simplify_expansion(auto_expansion)
Now only the certified lower-order terms remain.
B-terms are, in a nutshell, O-terms with explicitly specified bound constant and validity point. The term $$ B_{n\geq 10}(42 n^{3}) $$ represents an error term, valid from $n \geq 10$, that is bounded by $42 n^3$. Basic support for arithmetic (over univariate, monomial growth groups) is shipped with a standard installation of SageMath. Our specialized asymptotic ring extends this functionality to expansions involving the dependent variable $k = k(n)$.
7 * n + AR.B(5 / n, valid_from=10) + 3 / n ^ 2
dependent_bterms/structures.py:362: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. See https://github.com/sagemath/sage/issues/31922 for details. super().__init__(
The constant $53/10$ is obtained from automatically estimating $$ \frac{3}{n^2} = \frac{3}{n\cdot n} \leq \frac{3}{10 n}, $$ and then letting the existing B-term absorb this bound.
To avoid the accumulation of complicated symbolic expressions appearing when carrying out this automatic estimate, we have specified (via bterm_round_to
) above that B-term constants should be rounded:
AR.B(1 / n, valid_from=10) + n ^ (-4 / 3)
where the constant is $\big\lceil (1 + \frac{1}{10^{1/3}}) \cdot 10^3\big\rceil \cdot 10^{-3} = \frac{293}{200}$. This mechanism significantly improves performance for large expansions.
For B-terms to work with the dependent variable, some special absorption rules are in place:
AR.B(3 * k ^ 2 / n ^ 3, valid_from=10) + (1 - 2 * k + 3 * k ^ 2 - 4 * k ^ 3) / n ^ 5
We first estimate $$ \bigg\lvert\frac{1 - 2k + 3k - 4k^3}{n^5}\bigg\rvert \leq \frac{(1 + 2 + 3 + 4) k ^3}{n^5} = \frac{10 k^3}{n^5}. $$ As the power of $k$ in this bound is larger than the maximal power of $k$ in the B-term, we may not yet proceed as above (otherwise we would increase the upper bound of the B-term, which we must avoid). Instead, we use first use $k\leq n^{4/7}$, followed by $n\geq 10$ to obtain $$ \frac{10 k^3}{n^5} \leq \frac{10 k^2 n^{4/7}}{n^5} = \frac{10 k^2}{n^{31/7}} \leq \frac{10 k^2}{10^{10/7} \cdot n^3} = 10^{-3/7} \cdot \frac{k^2}{n^3}, $$ which the B-term now can absorb directly. Hence the value of the B-term constant is determined via $\lceil (3 + 10^{-3/7}) \cdot 10^3 \rceil \cdot 10^{-3} = \frac{3373}{1000}$.
This module also ships with support for B-term bounded Taylor expansions. From a technical point of view, the error term (in its Lagrange form) is determined rigorously using interval arithmetic.
arg = (1 + k) / n + AR.B(k ^ 3 / n ^ 3, valid_from=10)
ex = dbt.taylor_with_explicit_error(
lambda t: 1 / (1 - t ^ 2), arg, order=3, valid_from=10
)
ex
Simplification (involving partial absorption of coefficients) may lead to situations where terms of technically weaker growth cannot (as a limitation of the current implementation) be absorbed by the constructed error term. In this case the returned expansion is still correct; just not as compact as it could be.
dbt.simplify_expansion(ex)
By specifying simplify_bterm_growth=True
, simplifying an expansion also collapses the dependent variables in all B-terms, resulting in an expansion involving a single, "absolute" B-term.
dbt.simplify_expansion(ex, simplify_bterm_growth=True)