值分析實驗四:拉格朗日插值、牛頓插值與最小二乘擬合實踐指南)
簡介廣東工業(yè)大學數(shù)值分析課程實驗四的Python實驗報告完整覆蓋超定方程組最小二乘解與最小二乘擬合兩大核心實驗。報告為docx文檔共1個文件、112KB包含題目三、題目六及石油產(chǎn)量預(yù)測三道典型問題均附有可運行的Python源碼、算法介紹和結(jié)果分析。題目三基于最小二乘解的充要條件構(gòu)造正規(guī)方程組ATAxATb借助numpy的線性代數(shù)求解器高效算出兩組超定方程的解題目六以1和1/x為基函數(shù)建立線性組合模型調(diào)用sklearn的LinearRegression擬合觀察數(shù)據(jù)得到形如y2.01431.00931/x的擬合函數(shù)石油產(chǎn)量預(yù)測則演示了將數(shù)值方法應(yīng)用于實際數(shù)據(jù)建模的完整流程。讀者可從中學習最小二乘問題的矩陣推導(dǎo)、正規(guī)方程構(gòu)造、Python庫調(diào)用及結(jié)果分析方法適合正在學習數(shù)值分析、需要參考完整實驗報告或復(fù)習相關(guān)算法的高校學生。目前已有212人學習該資源。1. 某高校Python數(shù)值分析實驗四為什么代碼三分鐘跑完作業(yè)卻要寫一整晚數(shù)值分析這門課真正動手做起來和聽課時完全是兩個世界。某高校的Python數(shù)值分析實驗四表面上是插值和擬合兩個經(jīng)典主題——拉格朗日插值、牛頓插值、最小二乘擬合代碼用NumPy就能寫完跑通不過三分鐘。但真正消耗時間的是把課本上的公式變成能交代得清楚的程序把結(jié)果畫成能放進實驗報告的圖表以及處理那些課本沒寫、IDE也不會告訴你的邊界情況。這篇筆記按我實際完成實驗四的順序來寫從任務(wù)拆解、環(huán)境準備、算法實現(xiàn)到避坑排查每一步都給可復(fù)現(xiàn)的代碼和參數(shù)說明。適合第一次做數(shù)值分析實驗的學生也適合想快速拾起插值與擬合實現(xiàn)的工程師。2. 拆開實驗四的作業(yè)要求任務(wù)清單、環(huán)境準備與報告結(jié)構(gòu)2.1 先搞清實驗四考什么兩個主線任務(wù)和三類題型數(shù)值分析實驗四在多數(shù)高校的教學安排里主題都落在“插值法與曲線擬合”這一章。拆開來看主線任務(wù)基本是固定的用Python實現(xiàn)拉格朗日插值和牛頓插值再用最小二乘法做曲線擬合最后把結(jié)果和理論做對比。不同年份、不同老師的題目形式會有變化但底層要求逃不出三類題型。第一類是給定函數(shù)或數(shù)據(jù)表要求計算指定點的插值結(jié)果第二類是給一組觀測數(shù)據(jù)要求用多項式擬合出趨勢第三類是綜合題比如對某個病態(tài)函數(shù)做插值并討論誤差或者用擬合預(yù)測下一組數(shù)據(jù)點。先確認自己拿到的是哪類題再決定代碼怎么組織能省下大量返工時間。我見過不少同學上來就寫拉格朗日的循環(huán)寫完才發(fā)現(xiàn)題目要求的是擬合。更常見的坑是題目給了十個數(shù)據(jù)點但要求分別用三次、五次、七次多項式做擬合這時候如果沒提前把擬合邏輯封裝成函數(shù)后面每一個次數(shù)都要復(fù)制粘貼改參數(shù)實驗報告的代碼部分會顯得很亂查錯也麻煩。所以第一步不是寫代碼是把題目要求翻譯成一個清單要實現(xiàn)的算法有幾個、輸入輸出是什么、要求畫幾張圖、誤差分析要算哪些量。2.2 實驗環(huán)境準備conda創(chuàng)建虛擬環(huán)境與依賴清單實驗四的代碼依賴面不寬但版本不一致會在后面圖表上翻車。我一般會先建一個干凈的虛擬環(huán)境避免和機器上其他項目共用NumPy和SciPy。用conda創(chuàng)建虛擬環(huán)境的命令如下conda create -n numeric-analysis python3.11 conda activate numeric-analysis pip install numpy matplotlib scipy選Python 3.11而不是最新版本是因為NumPy和SciPy對最新Python版本的支持往往滯后幾個月裝完才發(fā)現(xiàn)某個依賴編譯失敗再回退更浪費時間。NumPy負責數(shù)組計算和多項式運算SciPy在擬合部分會用到curve_fitMatplotlib負責畫圖。這三個庫覆蓋面足夠pandas在這個實驗里用不上裝不裝看個人習慣。依賴安裝完以后建議順手驗證一下版本號是否匹配尤其是NumPy和SciPy之間的版本兼容。我遇到過NumPy 1.x和SciPy 1.11搭配時某個接口行為變化導(dǎo)致polyfit返回結(jié)果格式不同。驗證方式很簡單在Python交互環(huán)境里分別import并打印版本號確認能正常加載再開始寫實驗代碼。如果用的是機房預(yù)裝的環(huán)境版本往往偏舊建議先確認能不能裝新包不能裝就基于現(xiàn)有版本調(diào)整寫法別到最后一刻才暴露問題。2.3 實驗報告的結(jié)構(gòu)算法原理、程序?qū)崿F(xiàn)、結(jié)果分析三位一體實驗報告怎么寫決定了這份作業(yè)的最終成績。數(shù)值分析實驗的評分點通常有三個算法原理是否說清楚、代碼是否能跑出正確結(jié)果、結(jié)果分析是否有深度。三者缺一不可但很多同學只重視代碼原理部分抄課本分析部分寫“圖像符合預(yù)期”這等于把最容易拿分的部分放棄了。我的習慣是先在報告里畫一個整體框架再按照框架去補內(nèi)容。第一部分寫算法原理包括公式推導(dǎo)和算法步驟不需要長篇大論但要寫清楚公式中每個符號的含義比如插值節(jié)點、基函數(shù)、差商。第二部分寫程序?qū)崿F(xiàn)代碼按功能拆分關(guān)鍵函數(shù)要給注釋。第三部分寫結(jié)果分析這一部分要包含數(shù)值結(jié)果和圖像的對比以及誤差分析——插值法算出的值和理論值差多少、擬合的殘差有多大、為什么會有這個誤差。整份報告的邏輯是讀者只看報告不看你跑代碼也能復(fù)現(xiàn)你的結(jié)果這才是一份合格的實驗報告。3. 拉格朗日插值與牛頓插值從公式到Python實現(xiàn)3.1 拉格朗日插值法的數(shù)學原理與代碼實現(xiàn)插值問題的本質(zhì)是已知n1個數(shù)據(jù)點找一條通過所有這些點的曲線。拉格朗日插值的思想最直白構(gòu)造一組基函數(shù)每個基函數(shù)在某個數(shù)據(jù)點上取值為1在其他數(shù)據(jù)點上取值為0然后把所有基函數(shù)加權(quán)疊加。權(quán)重就是對應(yīng)數(shù)據(jù)點的函數(shù)值。這樣做的好處是公式對稱、好理解代碼實現(xiàn)也不需要額外存儲中間量。import numpy as np def lagrange_interp(x_points, y_points, x_eval): 拉格朗日插值計算單個點 x_eval 處的插值結(jié)果 x_points: 插值節(jié)點數(shù)組例如 [1, 2, 3] y_points: 對應(yīng)的函數(shù)值數(shù)組例如 [1, 4, 9] x_eval: 需要求插值的點可以是標量或數(shù)組 n len(x_points) if n 0: raise ValueError(插值節(jié)點不能為空) total 0.0 for i in range(n): term y_points[i] for j in range(n): if j ! i: term * (x_eval - x_points[j]) / (x_points[i] - x_points[j]) total term return total這段代碼的邏輯是兩層循環(huán)外層遍歷每個數(shù)據(jù)點內(nèi)層累乘計算對應(yīng)基函數(shù)在當前求值點x_eval處的值。內(nèi)層循環(huán)里分母是x_points[i] - x_points[j]當x_eval恰好等于某個插值節(jié)點時對應(yīng)項的分母會精確抵消成一其他項因為分子出現(xiàn)零而整個為0最終返回該節(jié)點的函數(shù)值這是拉格朗日插值最基本的性質(zhì)。代碼里加了個空節(jié)點檢查防止傳入空數(shù)組時報出難以理解的numpy錯誤。用的時候注意兩個參數(shù)語義x_points是插值節(jié)點而非插值區(qū)間端點它決定多項式的次數(shù)n個節(jié)點對應(yīng)n-1次多項式。x_eval可以是單個數(shù)值也可以是numpy數(shù)組函數(shù)內(nèi)部會自動做廣播。實測中對數(shù)組求值時這個函數(shù)會在每個元素上獨立執(zhí)行兩層循環(huán)數(shù)據(jù)量上千點時速度會明顯下降所以如果只需要在特定幾個點求值不要傳一個很長的密集數(shù)組這屬于代碼效率和精度無關(guān)但和體驗相關(guān)的問題。3.2 牛頓插值法差商表與遞推實現(xiàn)牛頓插值和拉格朗日插值數(shù)學上等價但實現(xiàn)思路不同。牛頓插值通過構(gòu)造差商表來逐步構(gòu)建多項式它的優(yōu)勢在于當新增一個插值節(jié)點時不需要重寫所有基函數(shù)只需在原有多項式上加一項。這個性質(zhì)在實驗里體現(xiàn)得最明顯的是題目要求先取前三個點插值看結(jié)果再取前四個點插值看結(jié)果用牛頓插值可以復(fù)用之前的計算。def newton_divided_differences(x_points, y_points): 計算差商表返回對角線上的差商系數(shù)數(shù)組 n len(x_points) coef np.array(y_points, dtypefloat) for j in range(1, n): for i in range(n - 1, j - 1, -1): coef[i] (coef[i] - coef[i - 1]) / (x_points[i] - x_points[i - j]) return coef def newton_interp(coef, x_points, x_eval): 用差商系數(shù)計算牛頓插值多項式在 x_eval 處的值 coef: newton_divided_differences 的返回值 n len(coef) result coef[0] for i in range(1, n): term coef[i] for j in range(i): term * (x_eval - x_points[j]) result term return result差商表計算是原地更新的coef數(shù)組在每一輪外層循環(huán)中被覆蓋最終coef[i]存放的是第i階差商。注意內(nèi)層循環(huán)從后向前遍歷這保證計算新值時用到的是上一輪的結(jié)果而不是本輪已經(jīng)覆蓋的值順序反了整個差商表就是錯的。牛頓插值的求值過程用到了嵌套乘法從最高次項開始逐層提取公因子這樣比直接展開多項式運算量更小也更符合數(shù)值分析教材里對秦九韶算法的介紹。實操中差商表函數(shù)只在構(gòu)造階段調(diào)用一次之后對多個x_eval求值時只需要反復(fù)調(diào)用newton_interp。如果你要插值的點有幾百上千個這個做法的優(yōu)勢非常明顯——差商構(gòu)造是O(n2)而每個點求值是O(n)。拉格朗日插值對每個求值點都要重新計算所有基函數(shù)同樣是O(n2)但乘在點的數(shù)量上數(shù)據(jù)量一大差距就拉開了。3.3 用matplotlib畫出插值效果對比圖實驗報告里最直觀的內(nèi)容是一張插值效果圖原始數(shù)據(jù)點、拉格朗日插值曲線、牛頓插值曲線在同一坐標系中展示。畫圖代碼不長但有兩個細節(jié)要注意插值曲線的橫坐標要足夠密不然曲線會顯得很生硬縱坐標范圍要留出余量避免曲線在邊緣處超出畫布。import matplotlib.pyplot as plt x_points np.array([0.0, 1.0, 2.0, 3.0, 4.0]) y_points np.array([1.0, 2.0, 1.5, 3.0, 2.8]) x_dense np.linspace(0, 4, 200) fig, ax plt.subplots(figsize(8, 5)) ax.plot(x_points, y_points, o, label原始數(shù)據(jù)點) ax.plot(x_dense, lagrange_interp(x_points, y_points, x_dense), -, label拉格朗日插值) coef newton_divided_differences(x_points, y_points) ax.plot(x_dense, newton_interp(coef, x_points, x_dense), --, label牛頓插值) ax.set_xlabel(x) ax.set_ylabel(y) ax.legend() ax.grid(True, linestyle--, alpha0.6) plt.show()畫圖時x_dense用np.linspace(0, 4, 200)生成200個均勻分布的點具體點數(shù)取決于插值多項式的次數(shù)和區(qū)間跨度一般200到500足夠。如果兩條插值曲線完全重合說明兩個算法在精度上一致這是正常的如果出現(xiàn)細微差異優(yōu)先檢查差商表的迭代順序是否正確。對比圖存在的意義是驗證兩個算法結(jié)果一致順帶檢查曲線的形狀是否符合直覺。4. 最小二乘曲線擬合把公式擬合到數(shù)據(jù)點上的完整流程4.1 最小二乘原理與numpy.polyfit最小實現(xiàn)擬合和插值的核心區(qū)別在于插值要求曲線嚴格穿過每個數(shù)據(jù)點擬合只要求曲線在整體上最接近數(shù)據(jù)點。最小二乘的思想是找一組參數(shù)讓模型計算值與觀測值的平方誤差之和最小。平方誤差比絕對誤差更敏感而且方便求導(dǎo)所以成為最常用的擬合準則。import numpy as np x_data np.array([0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]) y_data np.array([0.1, 0.8, 1.8, 2.9, 5.1, 7.2, 10.0]) degree 2 coeffs np.polyfit(x_data, y_data, degree) p np.poly1d(coeffs) print(擬合系數(shù), coeffs) print(擬合多項式, p)np.polyfit返回的是多項式系數(shù)從最高次到常數(shù)項排列系數(shù)順序和poly1d的輸入是對應(yīng)的。degree參數(shù)是最關(guān)鍵的調(diào)試項取1時是線性擬合取2時是拋物線擬合取大了會出現(xiàn)過擬合——曲線為了貼近個別數(shù)據(jù)點而劇烈抖動尤其是在數(shù)據(jù)本身不是高階多項式的情況下。判斷次數(shù)是否合適的標準很簡單看擬合曲線走勢是否符合數(shù)據(jù)的物理含義再看殘差是否隨機分布而不是呈現(xiàn)系統(tǒng)性偏差。poly1d是把系數(shù)數(shù)組包裝成可以直接調(diào)用的多項式對象調(diào)用p(x_eval)就能批量求值。這里有個小細節(jié)polyfit內(nèi)部用的是基于SVD的穩(wěn)定算法對于次數(shù)不超過8的多項式擬合很少出現(xiàn)數(shù)值問題但超過10次就要警惕矩陣病態(tài)結(jié)果可能不可信。所以實驗題里如果要求擬合次數(shù)特別高建議檢查一下擬合系數(shù)是否出現(xiàn)數(shù)量級異常的大值那通常是條件數(shù)過大導(dǎo)致的數(shù)值性翻車。4.2 自定義函數(shù)擬合scipy.optimize.curve_fit的使用實驗題里有時候不要求多項式擬合而是指定一個函數(shù)形式比如指數(shù)衰減模型或者帶偏移的正弦函數(shù)。np.polyfit只支持多項式這時候要換用scipy的curve_fit它可以擬合任意你寫出的Python函數(shù)。核心用法是先定義一個函數(shù)形式函數(shù)的第一個參數(shù)是自變量后面是待擬合參數(shù)。from scipy.optimize import curve_fit def exp_model(x, a, b, c): 指數(shù)衰減加常數(shù)偏移的擬合模型 return a * np.exp(-b * x) c popt, pcov curve_fit(exp_model, x_data, y_data, p0[1.0, 1.0, 0.0]) a_opt, b_opt, c_opt popt print(f擬合參數(shù): a{a_opt:.4f}, b{b_opt:.4f}, c{c_opt:.4f}) x_smooth np.linspace(x_data.min(), x_data.max(), 100) y_fit exp_model(x_smooth, *popt)p0是參數(shù)初值這個參數(shù)在很多時候決定了擬合能不能收斂。初值差得太遠算法可能陷入局部極小值甚至直接報錯。給p0的經(jīng)驗法則是先看數(shù)據(jù)點的取值范圍大致估計一下參數(shù)的量級。比如數(shù)據(jù)y值在0到10之間c的初值可以設(shè)為數(shù)據(jù)中點或最小值附近a的初值設(shè)為y的跨度b的初值根據(jù)曲線衰減的快慢估一個正數(shù)。如果你發(fā)現(xiàn)擬合結(jié)果明顯不合理最先該改的是p0而不是模型本身。curve_fit返回的pcov是參數(shù)協(xié)方差矩陣對角線元素開根號是參數(shù)的標準差代表擬合參數(shù)的不確定度。實驗報告里如果想體現(xiàn)嚴謹性可以把參數(shù)誤差也打印出來。當協(xié)方差矩陣里的值大到離譜時往往說明模型參數(shù)之間存在強相關(guān)性或者數(shù)據(jù)量不足以確定這么多參數(shù)這時候的擬合系數(shù)雖然能算出數(shù)但不能當作物理解釋使用。這個點算是一個隱藏的知識點寫在報告的分析部分會很加分。4.3 擬合效果的量化評估殘差、R方與可視化擬合做完不評估就寫報告等于黑匣子輸出直接交差。評估擬合質(zhì)量最常用的是三個量殘差、均方根誤差和R方。殘差是每個數(shù)據(jù)點的觀測值減擬合值R方表示擬合曲線解釋了數(shù)據(jù)方差的百分比越接近1越好。residuals y_data - exp_model(x_data, *popt) ss_res np.sum(residuals**2) ss_tot np.sum((y_data - np.mean(y_data))**2) r_squared 1 - ss_res / ss_tot rmse np.sqrt(np.mean(residuals**2)) print(fR方 {r_squared:.4f}) print(f均方根誤差 RMSE {rmse:.4f})注意R方有一個陷阱當模型形式比較復(fù)雜、參數(shù)很多時R方會虛高甚至接近1但這不代表模型真的好。一個十次多項式擬合十個數(shù)據(jù)點R方必然是1但那完全沒有預(yù)測意義。所以評估時要同時看殘差圖——如果殘差隨x增大而增大說明模型形式不對如果殘差呈現(xiàn)波浪形說明漏掉了周期性分量。這些判斷是數(shù)值分析實驗最有價值的訓(xùn)練比單純算對拉格朗日插值結(jié)果重要得多。把殘差圖畫出來和擬合效果圖畫在一起報告的分析部分立刻有了深度。5. 實驗四避坑指南5個最常見的翻車點與排查方法5.1 拉格朗日插值次數(shù)過高導(dǎo)致龍格現(xiàn)象數(shù)據(jù)越多結(jié)果越離譜現(xiàn)象用拉格朗日插值去逼近某些連續(xù)函數(shù)插值節(jié)點增加到十幾個甚至更多插值曲線在區(qū)間兩端劇烈震蕩誤差反而比少用幾個節(jié)點時更大。原因這是數(shù)值分析教材里反復(fù)強調(diào)的龍格現(xiàn)象。拉格朗日插值多項式在等距節(jié)點下對龍格函數(shù)、絕對值函數(shù)這類目標做高次逼近時插值余項在端點附近會放大多項式次數(shù)越高震蕩越明顯。解決明確實驗四的題目通常只要求4到6個節(jié)點的插值不需要追求高次。如果題目要求對比不同節(jié)點數(shù)下的誤差把插值點數(shù)從3逐個增加到10畫誤差曲線讓讀者直觀看到誤差先降后升的過程這本身就是一份合格的現(xiàn)象分析。如果實際工程中遇到類似需求應(yīng)該改用分段插值或樣條插值而不是硬上高次多項式。5.2 圖表的橫縱坐標出現(xiàn)方塊字中文標注全部亂碼現(xiàn)象matplotlib畫圖時標題和圖例里的中文顯示成一個個小方塊英文和數(shù)字正常實驗報告截圖里一眼就能看出問題。原因matplotlib默認字體不包含中文字形需要顯式指定中文字體。Windows系統(tǒng)一般有SimHei或Microsoft YaHeiLinux和macOS的字體名不同用系統(tǒng)自帶字體名逐個嘗試。解決在畫圖代碼最前面加上字體設(shè)置讓matplotlib全局使用中文字體如下所示import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei, PingFang SC] plt.rcParams[axes.unicode_minus] False第二行去掉坐標軸負號的特殊處理是因為切換了中文字體之后負號有可能顯示成一個奇怪的方框。這個問題屬于程序能跑但報告不能看的隱形翻車查錯成本高提前設(shè)置好就能完全避免。5.3 差商表計算順序?qū)懛磁nD插值結(jié)果對不上拉格朗日現(xiàn)象牛頓插值和拉格朗日插值結(jié)果不一致差距可能很小也可能很大越小規(guī)模的數(shù)據(jù)差距越小很多同學因此沒發(fā)現(xiàn)。原因newton_divided_differences函數(shù)里內(nèi)層循環(huán)的方向錯了。差商表必須從后向前原地更新如果寫成從前向后計算新的差商時用的是已經(jīng)被本輪覆蓋過的值導(dǎo)致差商全部錯誤。數(shù)據(jù)點少時誤差不明顯數(shù)據(jù)點多時完全對不上。解決內(nèi)層循環(huán)固定使用for i in range(n - 1, j - 1, -1)從后往前遍歷。排查思路也很簡單用三個點的手工差商計算結(jié)果和Python輸出對比如果差商對不上問題就在循環(huán)方向。這類錯誤的特點是代碼能跑、結(jié)果貼近但不對最容易在實驗報告的誤差分析部分暴露靠直覺很難發(fā)現(xiàn)。5.4 擬合結(jié)果出現(xiàn)巨大系數(shù)多項式次數(shù)太高導(dǎo)致矩陣病態(tài)現(xiàn)象polyfit指定degree9或更高時擬合系數(shù)出現(xiàn)10的6次方以上的大數(shù)擬合曲線在數(shù)據(jù)點之間劇烈波動部分區(qū)間甚至超出數(shù)據(jù)范圍好幾倍。原因高次多項式擬合的等效設(shè)計矩陣條件數(shù)隨次數(shù)指數(shù)增長數(shù)據(jù)點x跨度大時尤其嚴重。矩陣接近奇異SVD分解得到的解被微小舍入誤差放大系數(shù)自然不穩(wěn)定。解決首先判斷題目是否真的要求高次擬合。如果要求做不同次數(shù)擬合的對比把次數(shù)范圍控制在1到6之間重點觀察擬合誤差變化趨勢。如果必須擬合高次多項式考慮先對x數(shù)據(jù)做歸一化把數(shù)據(jù)平移到零均值并縮放到單位方差再擬合最后把系數(shù)還原回原始坐標。歸一化這步在實驗報告里是加分項能體現(xiàn)你對數(shù)值穩(wěn)定性的理解。5.5 求值點落在插值節(jié)點范圍之外結(jié)果完全失控現(xiàn)象用插值函數(shù)計算區(qū)間外的點計算結(jié)果非常大和真實函數(shù)值差出幾個數(shù)量級有的同學以為是代碼精度不夠。原因插值多項式只在節(jié)點覆蓋的區(qū)間內(nèi)有可靠逼近能力。區(qū)間外沒有任何數(shù)據(jù)點約束多項式形狀高次項起主導(dǎo)作用結(jié)果必然外溢。這是插值方法的固有屬性不是bug。解決求值前先檢查x_eval是否在x_points的范圍內(nèi)。如果題目故意要求計算外推值那么在報告里要明確記錄這個現(xiàn)象用誤差對比說明外推不可靠這屬于正面的實驗結(jié)果。如果在做擬合預(yù)測用polyfit擬合出的多項式做短距離預(yù)測是可行的做遠距離預(yù)測同樣會失效。邊界意識是從數(shù)值分析實驗里能帶走的最重要工程習慣。6. 用一份可視化腳本把實驗結(jié)果整理成答辯圖表實驗四答辯或提交報告時圖表質(zhì)量往往直接影響印象分。同樣是解決同一個問題一個用默認繪圖風格、圖例位置遮擋曲線、坐標軸沒標單位和另一個圖面干凈、曲線粗細分明、每個子圖都有標題和注釋給閱卷人的感受完全不同。整理圖表這一步建議獨立寫一個腳本不要和算法代碼混在一起輸出為高分辨率圖片再插入報告而不是直接截圖。import matplotlib.pyplot as plt import numpy as np fig, axes plt.subplots(1, 3, figsize(14, 4)) # 第一個子圖插值結(jié)果對比 axes[0].plot(x_points, y_points, o, label數(shù)據(jù)點) axes[0].plot(x_dense, lagrange_interp(x_points, y_points, x_dense), label拉格朗日) coef newton_divided_differences(x_points, y_points) axes[0].plot(x_dense, newton_interp(coef, x_points, x_dense), --, label牛頓) axes[0].set_title(插值結(jié)果對比) axes[0].legend() # 第二個子圖擬合效果 axes[1].plot(x_data, y_data, o, label觀測數(shù)據(jù)) axes[1].plot(x_smooth, y_fit, -, label擬合曲線) axes[1].set_title(最小二乘擬合) # 第三個子圖殘差分布 axes[2].plot(x_data, residuals, o-, label殘差) axes[2].axhline(0, colorgray, linestyle--) axes[2].set_title(擬合殘差分布) axes[2].legend() fig.tight_layout() plt.savefig(experiment4_summary.png, dpi200, bbox_inchestight) plt.show()一處細節(jié)是plt.savefig里的參數(shù)dpi至少200才夠打印清晰bbox_inchestight可以把空白邊緣裁掉避免圖片四周留白過多。如果你是準備提交電子版報告300dpi更好圖片文件大一點沒關(guān)系打印效果勻稱。另一個細節(jié)是每個子圖的標題要能自解釋也就是說讀者不看正文只看圖就知道這張圖在表達什么這是實驗報告圖表規(guī)范的基本要求多數(shù)同學沒意識到所以認真做反而會留下印象。我自己的習慣是在畫圖腳本開頭放一段注釋記錄這份圖表對應(yīng)的題目要求、數(shù)據(jù)文件、生成日期方便復(fù)查時快速定位。數(shù)值分析實驗四做完回頭看最大的收獲往往不是那幾個算法本身而是理解了“數(shù)據(jù)點給出的信息量是有限的任何試圖從有限數(shù)據(jù)外推的做法都必須說明假設(shè)和邊界”。這個意識在后面的課程和工程項目里反復(fù)被驗證。希望這篇筆記能幫你把實驗四從頭到尾走通拿到一個能進報告、能講清楚、也能經(jīng)得起提問的結(jié)果。本文還有配套的精品資源點擊獲取