[英]Python's eval() ignores discontinuities?
我正在構建一個 Python 圖形計算器,通過使用eval(function at x)
求解y
來繪制函數,直到我使用具有可移動不連續性的函數為止。 eval 不會返回類似NaN
東西,它只是評估如果它是連續的點會是什么。
例如,如果我計算(x-2)/((x^2)-4)
,該函數在技術上應該在 x=2 處未定義,但是在 x=2 處使用 eval() 返回 0.25 而不是 NaN,這是如果函數是連續的(技術上是極限),值會是多少。
有沒有辦法讓我解決這個問題並確定任何可移動的不連續性? 本質上,如果分母為零
用代碼編輯:
COMPUTATION_DISTANCE = 0.001
# THE DISTANCE BETWEEN EACH X VALUE WHEN PLOTTING POINTS. EVENTUALLY WE CONNECT A LINE BETWEEN ALL POINTS SEPERATED BY A VALUE OF COMPUTATION_DISTANCE.
# IF THE GRAPH IS ZOOMED, MULTIPLY THIS COMPUTATION DISTANCE BY A FACTOR OF THAT ZOOM
ASYMPTOTE = 2.0
#formula = "(x+2)**2" #just a fake formula to begin
formula = "(x-2)/((x**2)-4)" #just a fake formula to begin
view_size = 8.0
def draw_graph(event):
global alreadyGraphedDeriv #to prevent infinite loop of graphing deriv
alreadyGraphedDeriv = False
canvas.delete("all") #clear existing graph
draw_grid()
y_previous = 0.0
x = view_size * -1 #start at the negative of the view_size. so x =-8. then the loop wil keep repeating until x =+8 giving u all the x values. the loop takes care of the y values
while x <= view_size:
try:
y = eval(formula) #evaluate y at every point x
print(str(x) + ", " + str(y))
#if(y>1000000000000 or y < 1000000000000): #finding asymptotes
#print("Asymptote at (" + str(x) + ", " + str(y) + ") ")
except ValueError:
y = 1000000000
x = COMPUTATION_DISTANCE * view_size
print('Value error')
if eval(formula) < 0:
y *= -1
except:
print_formula("SYNTAX ERROR ")
print("syntax error")
break
try:
draw_line(x - COMPUTATION_DISTANCE * view_size, y_previous, x, y, "black") #(previous x, previous y, new x, new y, color)
except:
print_formula("NON-INT PWR (dbl click ^) ")
break
y_previous = y
x += COMPUTATION_DISTANCE * view_size
#print(" " + str(x - COMPUTATION_DISTANCE * view_size) + " " + str(y_previous) + " " + str(x) + " " + str(y) + " black")
#(previous x, previous y, new x, new y, color)
if alreadyGraphedDeriv is False:
alreadyGraphedDeriv = True
draw_derivative("event")
查看突出顯示的輸出。 它評估了 0.25 作為 x=2 的解決方案。
打印的y
值的數字截止表明您使用的是 Python 2。(Python 3 會顯示更多數字。)
在 Python 2 上, print
ing 或str
-ing a float 比 Python 3 更激進地截斷,因此不完全是2.0
值仍然可以顯示為2.0
。 由於累積的舍入誤差,您的x
並不是真正的2.0
,因此您的除法不是0/0。 它將一個非常小的數字除以一個非常小的數字,並且舍入誤差恰好可以解決,因此輸出為0.25
或非常接近。
如果您使用print(repr(x))
而不是print(str(x))
,您將看到足夠多的數字來使舍入誤差顯而易見。
另外,獲取 Python 3。
這是一個有趣的問題。 它無法在純 Python 中真正解決——要正確處理不連續性,您需要對表達式進行一些代數分析。 當然,您可以編寫一些函數來執行此操作,但使用現有系統(例如 Sympy ( https://sympy.org ))可能會方便得多。
您可能希望在要繪制的表達式中尋找不連續性,應用人類會使用的任何啟發式方法,例如,在分母中查找子表達式並查看它們是否在任何地方為零。 此外,您還想查看是否有任何不連續性是可移除的(因為 (x - 2)/(x**2 - 4) 中的 x = 2 是可移除的,因為您可以通過讓結果 = 1/4 來創建連續函數在 x = 2)。 最后,您將分別繪制不連續點之間的每個線段。
總而言之,這聽起來像是一個偉大的項目。 也許像這樣的智能繪圖儀可以為 Sympy 或其他項目做出貢獻,如果他們還沒有的話。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.