C++數(shù)值算法(第二版)
3.3 三次樣條插值
給定一個(gè)列表顯示的函數(shù)
yi=y(xi),i=0,1,2,...,N-1。特別注意在xj和xj+1之間的一個(gè)特殊的區(qū)間。該區(qū)間的線性插值公式為
(3.3.1)式和(3.3.2)式是拉格朗日插值公式(3.1.1)的特殊情況。
因?yàn)樗?span style="font-family:'Times New Roman'">(分段)線性的,(3.3.1)式在每一區(qū)間內(nèi)的二階導(dǎo)數(shù)為零,在橫坐標(biāo)為xj處的二階導(dǎo)數(shù)不定義或無限。三次樣條插值的目的就是要得到一個(gè)內(nèi)插公式,不論在區(qū)間內(nèi)亦或其邊界上,其一階導(dǎo)數(shù)平滑,二階導(dǎo)數(shù)連續(xù)。
做一個(gè)與事實(shí)相反的個(gè)假設(shè),除yi的列表值之外,我們還有函數(shù)二階導(dǎo)數(shù)y"的列表值,即一系列的yi"值,則在每個(gè)區(qū)間內(nèi),可以在(3.3.1)式的右邊加上一個(gè)三次多項(xiàng)式,其二階導(dǎo)數(shù)從左邊的yj"值線性變化到右邊的yj+1"值,這么做便得到了所需的連續(xù)二階導(dǎo)數(shù)。如果還將三次多項(xiàng)式構(gòu)造在xj和xj+1處為零,則不會(huì)破壞在終點(diǎn)xj和xj+1處與列表函數(shù)值yj和yj+1的一致性。
進(jìn)行一些輔助計(jì)算便可知,僅有一種辦法才能進(jìn)行這種構(gòu)造,即用
注意,(3.3.3)式和(3.3.4)式對(duì)自變量x的依賴,是完全通過A和B對(duì)x的線性依賴,以及C和D(通過A和B)對(duì)x的三次依賴而實(shí)現(xiàn)。
可以很容易地驗(yàn)證,y"事實(shí)上是該插值多項(xiàng)式的二階導(dǎo)數(shù)。使用ABCD的定義對(duì)x求(3.3.3)式的導(dǎo)數(shù),計(jì)算dA/dx dB/dx dC/dx dD/dx,結(jié)果為一階導(dǎo)數(shù)
因?yàn)?span style="font-family:'Times New Roman'">x=xj是A=1,x=x(i+1)時(shí)A=0,而B正相反,則(3.3.6)式表明y"恰為列表函數(shù)的二階導(dǎo)數(shù)。而且該二階導(dǎo)數(shù)在兩個(gè)區(qū)間(xj-1, xj)和(xj, xj+1)上是連續(xù)的。
現(xiàn)在唯一的問題是,假設(shè)yj"是已知的。而實(shí)際上并不知道。然而,仍不要求從(3.3.5)式算出的一階導(dǎo)數(shù)在兩個(gè)區(qū)間的邊界處是連續(xù)的。三次樣條的關(guān)鍵思想就在于要求這種連續(xù)性,并用它求得等式的二階導(dǎo)數(shù)yi"。
設(shè)(3.3.5)式在區(qū)間(xj-1, xj)上對(duì)x=xj求得的值,等于同一等式在區(qū)間(xj,x[j+1])上對(duì)x=xj求得的值,便可得到所求方程,是新整理得到(對(duì)j=1,......,N-2)
這意味著有N-2個(gè)線性方程,但卻有N個(gè)未知數(shù)yi",i=0,......,N-1。因此,存在一個(gè)具有兩個(gè)參數(shù)的可能解集。為求得唯一解,需要給出兩個(gè)進(jìn)一步的條件,一般取x0和x[n-1]處的邊界條件。最常見的做法有:
[1]設(shè)y[0"]和y[n-1]"之一或兩個(gè)都為零,得到所謂的自然三次樣條函數(shù),其一個(gè)或兩個(gè)邊界的二次導(dǎo)數(shù)為零。
[2]設(shè)y[n]"和y[n-1]"為(3.3.5)式計(jì)算得到的值,使得該插值函數(shù)的一階導(dǎo)數(shù)一個(gè)或兩個(gè)邊界處有特定的值。
三次樣條插值特別實(shí)用的原因之一在于,有兩個(gè)附加邊界條件的方程組(3.3.7),它不僅是線性的,而且是三對(duì)角的。每個(gè)yj"僅與其最鄰近的j+-1的值有關(guān)。因此,方程可以用三對(duì)角算法(參見2.4節(jié))在O(N)次運(yùn)算內(nèi)求解。該算法非常簡(jiǎn)明,很容易正確地構(gòu)造出樣條計(jì)算的程序。但是這使得程序不像(3.3.7)式的實(shí)現(xiàn)那樣完全透明,所以建議讀者將下面程序與 tridag程序(2.4節(jié))比較一上,仔細(xì)地研究。
重要的是要記住,在處理數(shù)組xi和yi構(gòu)成的列表函數(shù)時(shí),程序spline僅能調(diào)用一次。一旦調(diào)用過后,對(duì)任意的x,插值函數(shù)的值通過調(diào)用( 要多少次就調(diào)多少次)一個(gè)獨(dú)立的程序splint(spline interpolation的字頭縮寫)來得到。
Qt實(shí)現(xiàn)的Demo:
聯(lián)系客服