Sympy的简化功能似乎不会通过消除常见因素来简化Rational数字

时间:2018-01-25 17:42:11

标签: python sympy

我正在尝试使用Sympy来定义使用几何系列的重复小数部分。特别是,我试图在无穷远处找到序列限制(不是部分和限制)。我的代码适用于简单的情况,例如:

.33333333 + ...

但是当我尝试为更复杂的情况做这件事时,例如:

.400840084008 + ...

我的代码无法计算序列限制。当我对代码进行故障排除时,我在几何系列中得到了一个非常奇怪的有理数a的结果:geo_series = a *(r ** n)。我的代码是:

import numpy as np

import plotly.plotly as py
from plotly.graph_objs import Scatter, Figure

from sympy import limit_seq, lambdify, simplify, Symbol, Rational, Dummy

def seq_limit(seq, n):

   try:

        n_ = Dummy("n", integer=True, positive=True)

        L1 = limit_seq(seq.subs(n, 2*n_), n_)
        if L1 is None:
            print('Sympy evaluates sequence limit, L1, to None')
            return np.NaN

        L2 = limit_seq(seq.subs(n, 2*n_ + 1), n_)
        if L2 is None:
           print('Sympy evaluates sequence limit, L2, to None')
           return np.NaN
    except:
        return np.NaN

    if L1 == L2 :
        return L1
    else:
        print('L1 (even terms):', L1)
        print('L2 (odd terms):', L2)
        return np.NaN


def sum_limit(a, r):

    if np.absolute(r) >= 1 and a != 0:
        return np.NaN
    elif a == 0:
        return 0
    elif np.absolute(r) < 1:
        return a/(1 - r)


def geo_term_eval(func, i):

    term = lambdify(n, func)

    if term is None:
        print('Cannot evaluate a lambdified term')
    return term(i)


class Sequence(object):

    def __init__(self,geo_term, i):

        self.geo_term = geo_term
        self.sum = 0
        self.partial_sum = np.array([])
        self.dom = np.arange(i)
        self.rng = np.array([])
        self.is_positive = True
        self.is_alternating = True

        for i in self.dom:
            rng_val = geo_term_eval(self.geo_term, i)
            self.rng = np.append(self.rng, [rng_val])
            self.sum += rng_val
            self.partial_sum = np.append(self.partial_sum, [self.sum])

        sign_array = np.sign(self.rng)

        for i in self.dom:

            if self.rng[i] <= 0:
                self.is_positive = False
                break

        for i in self.dom[:-1]:

            if sign_array[i] == sign_array[i + 1]:
                self.is_alternating = False
                break

        self.seq_limit = seq_limit(geo_term, n)
        self.sum_limit = float(sum_limit(a, r))

        if self.seq_limit != np.NaN:
            self.seq_converges = True
        else:
            self.seq_converges = False

        if self.sum_limit != np.NaN:
            self.sum_converges = True
    else:
            self.sum_converges = False


py.sign_in('****', '***************')

a = Rational(501, 1250)  # same as Rational(4008, 10000)
r = Rational(1,-10000)

n = Symbol('n')
n_terms = 10
geo_term = simplify(a*r**n)

seq = Sequence(geo_term, n_terms)

if seq.seq_limit == np.NaN:
   print('Seq Limit:', 'None')
else:
   print ('Seq limit: ', seq.seq_limit)

if seq.sum_limit == np.NaN:
   print('Sum Limit', 'None')
else:
   print ('Sum limit: ', seq.sum_limit)

data = [Scatter(x=seq.dom, y=seq.rng)]
fig = Figure(data=data)

py.image.save_as(fig, filename='plots/geo_seq.png')

data = [Scatter(x=seq.dom, y=seq.partial_sum)]
fig = Figure(data=data)

py.image.save_as(fig, filename='plots/geo_sum.png')

Sympy为Rational(4008,10000)或Rational(501,1250)计算的合理比率是:7220170922600379/18014398509481984 我认为这是尝试计算限制时问题的根源。任何帮助将不胜感激。谢谢

1 个答案:

答案 0 :(得分:-1)

问题是一个简单的语法问题:r = Rational(501/1250)需要更改为r = Rational(501,1250)。当首先完成除法时,Rational函数会计算一个非简化比率,虽然这是正确的,但在调用其他Sympy函数时会导致问题。

相关问题