If we are dealing with a KroneckerDelta expression, i.e. KroneckerDelta(g(x), j),
we try to simplify it.
If we could simplify it, then we sum the resulting expression.
We already know we can sum a simplified expression, because only
simple KroneckerDelta expressions are involved.
If we couldn’t simplify it, there are two cases:
The expression is a simple expression: we return the summation,
taking care if we are dealing with a Derivative or with a proper
KroneckerDelta.
The expression is not simple (i.e. KroneckerDelta(cos(x))): we can do
nothing at all.
If the expr is a multiplication expr having a KroneckerDelta term:
First we expand it.
If the expansion did work, then we try to sum the expansion.
If not, we try to extract a simple KroneckerDelta term, then we have two
cases:
We have a simple KroneckerDelta term, so we return the summation.
We didn’t have a simple term, but we do have an expression with
simplified KroneckerDelta terms, so we sum this expression.
Perform a linear transformation x mapsto a x + b on the index variable
x. For a the only values allowed are pm 1. A new variable to be used
after the change of index can also be specified.
change_index(expr,var,trafo,newvar=None) where var specifies the
index variable x to transform. The transformation trafo must be linear
and given in terms of var. If the optional argument newvar is
provided then var gets replaced by newvar in the final expression.
However, the last result can be inconsistent with usual
summation where the index increment is always 1. This is
obvious as we get back the original value only for u
equal +1 or -1.
expr.reorder(*arg) reorders the limits in the expression expr
according to the list of tuples given by arg. These tuples can
contain numerical indices or index variable names or involve both.
expr.reorder_limit(x,y) interchanges two limit tuples. The
arguments x and y are integers corresponding to the index
variables of the two limits which are to be interchanged. The
expression expr has to be either a Sum or a Product.
Replace instances of the given dummy variables with explicit dummy
counterparts to make clear what are dummy variables and what
are real-world symbols in an object.
If the object supperts the “integral at” limit (x,) it
is not treated as a dummy, but the explicit form, (x,x)
of length 2 does treat the variable as a dummy.
If there were no dummies in the original expression, then the
the symbols which cannot be changed by subs() are clearly seen as
those with an underscore prefix.
modelparameters.sympy.concrete.gosper.gosper_normal(f, g, n, polys=True)[source]¶
Compute the Gosper’s normal form of f and g.
Given relatively prime univariate polynomials f and g,
rewrite their quotient to a normal form defined as follows:
\[\frac{f(n)}{g(n)} = Z \cdot \frac{A(n) C(n+1)}{B(n) C(n)}\]
where Z is an arbitrary constant and A, B, C are
monic polynomials in n with the following properties:
gcd(A(n), B(n+h)) = 1 forall h in mathbb{N}
gcd(B(n), C(n+1)) = 1
gcd(A(n), C(n)) = 1
This normal form, or rational factorization in other words, is a
crucial step in Gosper’s algorithm and in solving of difference
equations. It can be also used to decide if two hypergeometric
terms are similar or not.
This procedure will return a tuple containing elements of this
factorization in the form (Z*A,B,C).
and f(n) doesn’t depend on n, returns g_{n} - g(0) where
g_{n+1} - g_n = f_n, or None if s_n can not be expressed
in closed form as a sum of hypergeometric terms.
Detects and returns a recurrence relation from a sequence of several integer
(or rational) terms. The name of the function in the returned expression is
‘a’ by default; the main variable is ‘n’ by default. The smallest index in
the returned expression is always n (and never n-1, n-2, etc.).
This function is used internally by other functions from the
sympy.concrete.guess module. While most users may want to rather use the
function find_simple_recurrence when looking for recurrence relations
among rational numbers, the current function may still be useful when
some post-processing has to be done.
The function returns a vector of length n when a recurrence relation of
order n is detected in the sequence of rational numbers v.
If the returned vector has a length 1, then the returned value is always
the list [0], which means that no relation has been found.
While the functions is intended to be used with rational numbers, it should
work for other kinds of real numbers except for some cases involving
quadratic numbers; for that reason it should be used with some caution when
the argument is not a list of rational numbers.
This function is adapted from the Rate.m package for Mathematica
written by Christian Krattenthaler.
It tries to guess a formula from a given sequence of rational numbers.
In order to speed up the process, the ‘all’ variable is set to False by
default, stopping the computation as some results are returned during an
iteration; the variable can be set to True if more iterations are needed
(other formulas may be found; however they may be equivalent to the first
ones).
Another option is the ‘evaluate’ variable (default is True); setting it
to False will leave the involved products unevaluated.
By default, the number of iterations is set to 2 but a greater value (up
to len(l)-1) can be specified with the optional ‘niter’ variable.
More and more convoluted results are found when the order of the
iteration gets higher:
first iteration returns polynomial or rational functions;
second iteration returns products of rising factorials and their
inverses;
third iteration returns products of products of rising factorials
and their inverses;
etc.
The returned formulas contain symbols i0, i1, i2, … where the main
variables is i0 (and auxiliary variables are i1, i2, …). A list of
other symbols can be provided in the ‘variables’ option; the length of
the least should be the value of ‘niter’ (more is acceptable but only
the first symbols will be used); in this case, the main variable will be
the first symbol in the list.
In order to spare time, the user can select only some types of generating
functions (default being [‘all’]). While forgetting to use a list in the
case of a single type may seem to work most of the time as in: types=’ogf’
this (convenient) syntax may lead to unexpected extra results in some cases.
Discarding a type when calling the function does not mean that the type will
not be present in the returned dictionary; it only means that no extra
computation will be performed for that type, but the function may still add
it in the result when it can be easily converted from another type.
Two generating functions (lgdogf and lgdegf) are not even computed if the
initial term of the sequence is 0; it may be useful in that case to try
again after having removed the leading zeros.
N-th root of a rational function can also be detected (below is an example
coming from the sequence A108626 from http://oeis.org).
The greatest n-th root to be tested is specified as maxsqrtn (default 2).
Helps identifying a rational number from a float (or mpmath.mpf) value by
using a continued fraction. The algorithm stops as soon as a large partial
quotient is detected (greater than 10000 by default).
While the function is rather intended to help ‘identifying’ rational
values, it may be used in some cases for approximating real numbers.
(Though other functions may be more relevant in that case.)
>>> rationalize(pi,maxcoeff=250)355/113
See also
Several, like, The, that, global, rational, the, with, expansion, when, on, other
Product represents a finite or infinite product, with the first
argument being the general form of terms in the series, and the second
argument being (dummy_variable,start,end), with dummy_variable
taking all integer values from start through end. In accordance
with long-standing mathematical convention, the end term is included in
the product.
For finite products (and products with symbolic limits assumed to be finite)
we follow the analogue of the summation convention described by Karr [1],
especially definition 3 of section 1.4. The product:
with the upper limit value f(n) excluded. The product over an empty set is
one if and only if m = n:
\[\prod_{m \leq i < n} f(i) = 1 \quad \mathrm{for} \quad m = n\]
Finally, for all other products over empty sets we assume the following
definition:
\[\prod_{m \leq i < n} f(i) = \frac{1}{\prod_{n \leq i < m} f(i)} \quad \mathrm{for} \quad m > n\]
It is important to note that above we define all products with the upper
limit being exclusive. This is in contrast to the usual mathematical notation,
but does not affect the product convention. Indeed we have:
An example showing that the symbolic result of a product is still
valid for seemingly nonsensical values of the limits. Then the Karr
convention allows us to give a perfectly valid interpretation to
those products by interchanging the limits according to the above rules:
An explicit example of the Karr summation convention applied to products:
>>> P1=Product(x,(i,a,b)).doit()>>> P1x**(-a + b + 1)>>> P2=Product(x,(i,b+1,a-1)).doit()>>> P2x**(a - b - 1)>>> simplify(P1*P2)1
And another one:
>>> P1=Product(i,(i,b,a)).doit()>>> P1RisingFactorial(b, a - b + 1)>>> P2=Product(i,(i,a+1,b-1)).doit()>>> P2RisingFactorial(a + 1, -a + b - 1)>>> P1*P2RisingFactorial(b, a - b + 1)*RisingFactorial(a + 1, -a + b - 1)>>> simplify(P1*P2)1
Evaluate objects that are not evaluated by default like limits,
integrals, sums and products. All objects of this kind will be
evaluated recursively, unless some species were excluded via ‘hints’
or unless the ‘deep’ hint was set to ‘False’.
reverse_order(expr,*indices) reverses some limits in the expression
expr which can be either a Sum or a Product. The selectors in
the argument indices specify some indices whose limits get reversed.
These selectors are either variable names or numerical indices counted
starting from the inner-most limit tuple.
Examples
>>> from..importProduct,simplify,RisingFactorial,gamma,Sum>>> from..abcimportx,y,a,b,c,d>>> P=Product(x,(x,a,b))>>> Pr=P.reverse_order(x)>>> PrProduct(1/x, (x, b + 1, a - 1))>>> Pr=Pr.doit()>>> Pr1/RisingFactorial(b + 1, a - b - 1)>>> simplify(Pr)gamma(b + 1)/gamma(a)>>> P=P.doit()>>> PRisingFactorial(a, -a + b + 1)>>> simplify(P)gamma(b + 1)/gamma(a)
While one should prefer variable names when specifying which limits
to reverse, the index counting notation comes in handy in case there
are several symbols with the same name.
>>> S=Sum(x*y,(x,a,b),(y,c,d))>>> SSum(x*y, (x, a, b), (y, c, d))>>> S0=S.reverse_order(0)>>> S0Sum(-x*y, (x, b + 1, a - 1), (y, c, d))>>> S1=S0.reverse_order(1)>>> S1Sum(x*y, (x, b + 1, a - 1), (y, d + 1, c - 1))
Of course we can mix both notations:
>>> Sum(x*y,(x,a,b),(y,2,5)).reverse_order(x,1)Sum(x*y, (x, b + 1, a - 1), (y, 6, 1))>>> Sum(x*y,(x,a,b),(y,2,5)).reverse_order(y,x)Sum(x*y, (x, b + 1, a - 1), (y, 6, 1))
The notation for symbols is similar to the notation used in Sum or
Integral. product(f, (i, a, b)) computes the product of f with
respect to i from a to b, i.e.,
b_____product(f(n),(i,a,b))=||f(n)||i=a
If it cannot compute the product, it returns an unevaluated Product object.
Repeated products can be computed by introducing additional symbols tuples:
>>> from..importproduct,symbols>>> i,n,m,k=symbols('i n m k',integer=True)
Sum represents a finite or infinite series, with the first argument
being the general form of terms in the series, and the second argument
being (dummy_variable,start,end), with dummy_variable taking
all integer values from start through end. In accordance with
long-standing mathematical convention, the end term is included in the
summation.
For finite sums (and sums with symbolic limits assumed to be finite) we
follow the summation convention described by Karr [1], especially
definition 3 of section 1.4. The sum:
with the upper limit value f(n) excluded. The sum over an empty set is
zero if and only if m = n:
\[\sum_{m \leq i < n} f(i) = 0 \quad \mathrm{for} \quad m = n\]
Finally, for all other sums over empty sets we assume the following
definition:
\[\sum_{m \leq i < n} f(i) = - \sum_{n \leq i < m} f(i) \quad \mathrm{for} \quad m > n\]
It is important to note that Karr defines all sums with the upper
limit being exclusive. This is in contrast to the usual mathematical notation,
but does not affect the summation convention. Indeed we have:
An example showing that the symbolic result of a summation is still
valid for seemingly nonsensical values of the limits. Then the Karr
convention allows us to give a perfectly valid interpretation to
those sums by interchanging the limits according to the above rules:
Evaluate objects that are not evaluated by default like limits,
integrals, sums and products. All objects of this kind will be
evaluated recursively, unless some species were excluded via ‘hints’
or unless the ‘deep’ hint was set to ‘False’.
Return an Euler-Maclaurin approximation of self, where m is the
number of leading terms to sum directly and n is the number of
terms in the tail.
With m = n = 0, this is simply the corresponding integral
plus a first-order endpoint correction.
Returns (s, e) where s is the Euler-Maclaurin approximation
and e is the estimated error (taken to be the magnitude of
the first omitted term in the tail):
Check whether the function matches with the zeta function.
If it matches, then return a Piecewise expression because
zeta function does not converge unless s > 1 and q > 0
We divide the study of convergence of infinite sums and products in
two parts.
First Part:
One part is the question whether all the terms are well defined, i.e.,
they are finite in a sum and also non-zero in a product. Zero
is the analogy of (minus) infinity in products as
\(e^{-\infty} = 0\).
Second Part:
The second part is the question of convergence after infinities,
and zeros in products, have been omitted assuming that their number
is finite. This means that we only consider the tail of the sum or
product, starting from some point after which all terms are well
defined.
For example, in a sum of the form:
\[\sum_{1 \leq i < \infty} \frac{1}{n^2 + an + b}\]
where a and b are numbers. The routine will return true, even if there
are infinities in the term sequence (at most two). An analogous
product would be:
\[\prod_{1 \leq i < \infty} e^{\frac{1}{n^2 + an + b}}\]
This is how convergence is interpreted. It is concerned with what
happens at the limit. Finding the bad terms is another independent
matter.
Note: It is responsibility of user to see that the sum or product
is well defined.
There are various tests employed to check the convergence like
divergence test, root test, integral test, alternating series test,
comparison tests, Dirichlet tests. It returns true if Sum is convergent
and false if divergent and NotImplementedError if it can not be checked.
reverse_order(self,*indices) reverses some limits in the expression
self which can be either a Sum or a Product. The selectors in
the argument indices specify some indices whose limits get reversed.
These selectors are either variable names or numerical indices counted
starting from the inner-most limit tuple.
Examples
>>> from..importSum>>> from..abcimportx,y,a,b,c,d
>>> Sum(x,(x,0,3)).reverse_order(x)Sum(-x, (x, 4, -1))>>> Sum(x*y,(x,1,5),(y,0,6)).reverse_order(x,y)Sum(x*y, (x, 6, 0), (y, 7, -1))>>> Sum(x,(x,a,b)).reverse_order(x)Sum(-x, (x, b + 1, a - 1))>>> Sum(x,(x,a,b)).reverse_order(0)Sum(-x, (x, b + 1, a - 1))
While one should prefer variable names when specifying which limits
to reverse, the index counting notation comes in handy in case there
are several symbols with the same name.
>>> S=Sum(x**2,(x,a,b),(x,c,d))>>> SSum(x**2, (x, a, b), (x, c, d))>>> S0=S.reverse_order(0)>>> S0Sum(-x**2, (x, b + 1, a - 1), (x, c, d))>>> S1=S0.reverse_order(1)>>> S1Sum(x**2, (x, b + 1, a - 1), (x, d + 1, c - 1))
Of course we can mix both notations:
>>> Sum(x*y,(x,a,b),(y,2,5)).reverse_order(x,1)Sum(x*y, (x, b + 1, a - 1), (y, 6, 1))>>> Sum(x*y,(x,a,b),(y,2,5)).reverse_order(y,x)Sum(x*y, (x, b + 1, a - 1), (y, 6, 1))
Compute the summation of f with respect to symbols.
The notation for symbols is similar to the notation used in Integral.
summation(f, (i, a, b)) computes the sum of f with respect to i from a to b,
i.e.,
b
____
\ `
summation(f, (i, a, b)) = ) f
/___,
i = a
If it cannot compute the sum, it returns an unevaluated Sum object.
Repeated sums can be computed by introducing additional symbols tuples:
>>> from..importsummation,oo,symbols,log>>> i,n,m=symbols('i n m',integer=True)