- Python高性能編程(第2版)
- (美)米夏·戈雷利克等
- 1159字
- 2023-09-06 19:21:27
2.2 朱利亞集合簡介
朱利亞集合是一個有趣的CPU密集型問題,它是一個生成復雜圖形的分形數列,以加斯頓·朱利亞(Gaston Julia)的名字命名。
本書將介紹的代碼可能比你編寫的要長些,其中包括CPU密集型部分及一組顯式輸入。這讓我們能夠剖析CPU占用情況和RAM占用情況,從而明白哪部分代碼較多地占用了這兩項稀缺的計算資源。這里的實現并非最優的,這是有意為之的,旨在讓我們找出消耗內存的操作以及速度緩慢的語句。本章后面將修改一條速度緩慢的邏輯語句,還有一條消耗大量內存的語句,而第7章將顯著地縮短這個函數的執行時間。
我們將分析一個代碼塊,它使用復平面點c= ?0.62772?0.42193j生成朱利亞集合的偽灰度圖(如圖2-1所示)和純灰度圖(如圖2-3所示)。朱利亞集合是分別計算每個像素來生成的,這是一個高度并行問題,因為不同的點之間不共享任何數據。
如果選擇不同的c值,將得到不同的圖像。對于特定的c值,圖像有些區域計算起來較快,有些區域計算起來較慢,這對我們的分析大有裨益。
上面這個問題很有趣,因為每個像素都是通過循環計算得到的,但循環迭代的次數隨像素而異。在每次迭代中,系統都會檢查當前坐標會導致結果趨于無窮大還是受制于一個吸引子。在圖2-1中,對于特定的坐標,如果需要執行的迭代次數較少,就涂上深色,如果需要執行的迭代次數較多,就涂上白色。白色區域計算起來更復雜,因此生成它們需要的時間更長。

圖2-1 突出了細節的偽灰度朱利亞集合圖
我們定義一組需要檢查的z坐標,并使用下面的函數來計算復數z的平方加上c的結果:
f(z) = z2 + c
我們在循環中計算這個函數的結果,并使用abs判斷是否滿足繼續循環的條件。如果不滿足,就退出循環,并將迭代次數記錄下來。如果始終滿足繼續循環的條件,就在迭代maxiter次后結束循環。然后,根據迭代次數給復數點對應的像素著色。
計算迭代次數的偽代碼類似于下面這樣:
for z in coordinates: for iteration in range(maxiter): # limited iterations per point if abs(z) < 2.0: # has the escape condition been broken? z = z*z + c else: break # store the iteration count for each z and draw later
為幫助你弄明白這個函數,我們使用兩個坐標來訓練它。
先來看圖2-1左上角的坐標?1.8?1.8j。修改z值前,必須檢查條件abs(z) < 2是否滿足:
z = -1.8-1.8j print(abs(z)) 2.54558441227
由此可知,對于左上角的坐標,零次迭代時就不滿足繼續循環的條件,因為2.54 >= 2.0。因此,不用再修改z的值。對于這個坐標,輸出結果為0。
接下來看圖2-1中心坐標z=0+0j,并嘗試執行幾次迭代:
c = -0.62772-0.42193j z = 0+0j for n in range(9): z = z*z + c print(f"{n}: z={z: .5f}, abs(z)={abs(z):0.3f}, c={c: .5f}") 0: z=-0.62772-0.42193j, abs(z)=0.756, c=-0.62772-0.42193j 1: z=-0.41171+0.10778j, abs(z)=0.426, c=-0.62772-0.42193j 2: z=-0.46983-0.51068j, abs(z)=0.694, c=-0.62772-0.42193j 3: z=-0.66777+0.05793j, abs(z)=0.670, c=-0.62772-0.42193j 4: z=-0.18516-0.49930j, abs(z)=0.533, c=-0.62772-0.42193j 5: z=-0.84274-0.23703j, abs(z)=0.875, c=-0.62772-0.42193j 6: z= 0.02630-0.02242j, abs(z)=0.035, c=-0.62772-0.42193j 7: z=-0.62753-0.42311j, abs(z)=0.757, c=-0.62772-0.42193j 8: z=-0.41295+0.10910j, abs(z)=0.427, c=-0.62772-0.42193j
從上述輸出可知,在這些迭代中,條件abs(z) < 2都滿足。實際上,對于這個坐標,迭代300次時,繼續循環條件依然滿足。我們不知道要迭代多少次后,繼續循環條件才不滿足,也許是無窮次。通過指定最大迭代次數(maxiter)可以避免無限地循環下去。
圖2-2顯示了前50次的迭代結果。對于0+0j(帶圓圈的實線),看起來每隔7次迭代結果就重復,但不是完全重復,存在細微的差異。我們無法判斷迭代結果是始終在邊界內,還是迭代很多次后就會超出邊界,或是迭代幾次就會超出邊界。圖中的虛線表示的是位于+2處的邊界線。

圖2-2 朱利亞集合的兩個坐標的演化示例
對于坐標點?0.82+0j(帶菱形的虛線),第9次迭代后就超出了位于+2的邊界線,因此不再迭代下去。
- The Complete Rust Programming Reference Guide
- Mastering PHP Design Patterns
- Bulma必知必會
- 新手學Visual C# 2008程序設計
- 深入理解Java7:核心技術與最佳實踐
- C語言程序設計實踐教程
- MATLAB實用教程
- Mastering JavaScript Design Patterns(Second Edition)
- Mastering Android Development with Kotlin
- Advanced Express Web Application Development
- Babylon.js Essentials
- Visual Studio 2015高級編程(第6版)
- Android移動應用開發項目教程
- IPython Interactive Computing and Visualization Cookbook
- 軟件測試(慕課版)