简体   繁体   English

分段函数无穷级数的Sympy图,符号为索引问题

[英]Sympy plot of infinite series of piecewise function, symbol as index issue

I'm having trouble creating this Function to plot in python using Sympy, where {r1, r2, r3, ...} are an enumeration of the rationals.我在使用 Sympy 创建此函数以在 python 中绘图时遇到问题,其中 {r1, r2, r3, ...} 是有理数的枚举。

I've tried the following to define each function separately, but the main issue is trying to use a sympy symbol as an index for my rationals list:我尝试了以下方法来分别定义每个函数,但主要问题是尝试使用 sympy 符号作为我的rationals列表的索引:

import numpy as np
from sympy.abc import x, n
from sympy import Piecewise, piecewise_fold, Sum, IndexedBase, oo, Function

rationals = 10*np.random.rand(10000)

u = Function('u')(x, n)
class u(Function):
    
    '''A function u_n(x) which returns 1/2^n if x > r_n, and 0 otherwise, 
    where r_n taken from an enumeration of the rationals.'''
    
    nargs = 2
    @classmethod
    def eval(cls, x, n):
        if x > rationals[n]:
            return 1/2**n
        else:
            return 0
        
h = Function('h')(x)
class h(Function):
    
    '''Function which evaluates the summation of u_n(x)'''
    
    @classmethod
    def eval(cls, x):
        return Sum(u(x, n), (0, n, oo))

I get the following error when evaluating x > rationals[n]:评估 x >rationals[n] 时出现以下错误:

IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

How do I go around this problem?我该如何解决这个问题? Are there better ways to write this code if all I want to do is plot h(x), and perhaps make a gif with a slider to see how the function changes as n -> oo?如果我想要做的只是绘制 h(x),并且可能制作带有滑块的 gif 以查看函数如何随 n -> oo 变化,那么是否有更好的方法来编写此代码?

There are a couple minor issues with the code:代码有几个小问题:

Sum(u(x, n), (0, n, oo)) should be instead Sum(u(x, n), (n, 0, oo)) Sum(u(x, n), (0, n, oo))应该改为Sum(u(x, n), (n, 0, oo))

Also there's no need to write u = Function('u')(x, n) because this is overwritten by the class definition anyway.也没有必要写u = Function('u')(x, n)因为它无论如何都被类定义覆盖了。

But more fundamentally you can't index into a numpy array using a sympy symbol as this will always return an IndexError .但更根本的是,您不能使用 sympy 符号索引到 numpy 数组,因为这将始终返回IndexError In addition, Sum where the limits are infinite is only going to be helpful for well known symbolic summations like Sum(1/n**2, (n, 1, oo)) which you can call the methods .doit() on to obtain pi**2/6 (or .evalf() will give a floating point result).此外,极限为无穷大的Sum只会对众所周知的符号求和有用,例如Sum(1/n**2, (n, 1, oo))您可以调用方法.doit()到获得pi**2/6 (或.evalf()将给出浮点结果)。

However, the .doit() method for an infinite Sum won't be able to compute a result for your custom function u as is.但是,无限Sum.doit()方法将无法按.doit()计算自定义函数u的结果。 It seems to me that you might have better luck trying to write this using purely numerical functions from numpy or scipy.在我看来,尝试使用 numpy 或 scipy 中的纯数值函数来编写它可能会更幸运。

Sticking with sympy though I think you want something like this?尽管我认为你想要这样的东西,但坚持同情?

import numpy as np
from sympy import Function, Sum, symbols, oo, S, plot

rationals = 10*np.random.rand(10000)

class u(Function):
    
    '''A function u_n(x) which returns 1/2^n if x > r_n, and 0 otherwise, 
    where r_n taken from an enumeration of the rationals.'''
    
    nargs = 2
    @classmethod
    def eval(cls, x, n):
        # a guard like this will prevent your IndexError (but you'll be left with an unevaluated `u(x, n)` if you pass non numeric arguments to `u`
        if x.is_Number and x.is_real and n.is_Integer: 
            if x > rationals[n]:
                return 1/2**n
            else:
                return S(0)  # sympy's plot apparently requires a 'sympified' integer

n = symbols("n", integer=True)
        
class h(Function):
    
    '''Function which evaluates the summation of u_n(x)'''
    
    @classmethod
    def eval(cls, x, lim):
        return Sum(u(x, n), (n, 0, lim)).doit()


numeric_result = h(2, 100)
print(numeric_result) # rational
print(numeric_result.evalf()) # float
print(h(2, oo)) # unevaluated

x = symbols("x")
p = plot(h(x,100))
p.show()


Running this code produces eg:运行此代码会产生例如:

159056405582528143525572386825/633825300114114700748351602688
0.250946760178067
Sum(u(2, n), (n, 0, oo))

so with the infinite upper limit sympy just returns the result unevaluated.所以在无限上限的情况下,sympy 只返回未评估的结果。

Here's the plot:这是情节: 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM