[英]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 只返回未评估的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.