// IntegralRumberg /* ------------------------------------------------------ 作者 : Black Ghost 日期 : 2018-12-12 版本 : 0.0.0 ------------------------------------------------------ Rumberg(龙贝格)求积分公式 理论: 对于积分 b |f(x)dx a b-a T1 = -----(f(a)+f(b)) 2 1 b-a N b-a T2N = ---TN + -----Sum f(a+(2j-1)------) 2 2N j=1 2N N=2^(k-1), k=1,2,3,... 1 4T2N-TN SN = T2N + ---(T2N-TN) = -------- 3 4-1 1 4^2S2N-SN CN = S2N + ----(S2N-SN) = ----------- 15 4^2-1 1 4^3C2N-CN RN = C2N + ----(C2N-CN) = ----------- 63 4^3-1 参考 李信真, 车刚明, 欧阳洁, 等. 计算方法. 西北工业大学 出版社, 2000, pp 162-164. ------------------------------------------------------ 输入 : fun 被积分函数 a, b 积分范围 tol 控制误差 Nn 最大循环步数 输出 : sol 解 err 解出标志:false-未解出或达到步数上限; true-全部解出 ------------------------------------------------------ */ package goNum import ( "math" ) // IntegralRumberg Rumberg(龙贝格)求积分公式 func IntegralRumberg(fun func(float64) float64, a, b, tol float64, Nn int) (float64, bool) { /* Rumberg(龙贝格)求积分公式 输入 : fun 被积分函数 a, b 积分范围 tol 控制误差 Nn 最大循环步数 输出 : sol 解 err 解出标志:false-未解出或达到步数上限; true-全部解出 */ T := make([]float64, 0) //梯形序列 S := make([]float64, 0) //辛浦生序列 C := make([]float64, 0) //柯特斯序列 R := make([]float64, 0) //龙贝格序列 //第一步 temp0 := (b - a) * (fun(a) + fun(b)) / 2.0 T = append(T, temp0) //T[0]=T1 //第二步, k=1 temp0 = 0.0 for j := 1; j < PowIInt(2, 0)+1; j++ { temp0 += fun(a + (2.0*float64(j)-1.0)*(b-a)/2.0) } temp0 = T[0]/2.0 + temp0*(b-a)/2.0 T = append(T, temp0) //T[1]=T2 temp1 := T[1] + (T[1]-T[0])/3.0 S = append(S, temp1) //S[0]=S1 //第三步, k=2 temp0 = 0.0 for j := 1; j < PowIInt(2, 1)+1; j++ { temp0 += fun(a + (2.0*float64(j)-1.0)*(b-a)/(2.0*2.0)) } temp0 = T[1]/2.0 + temp0*(b-a)/(2.0*2.0) T = append(T, temp0) //T[2]=T4 temp1 = T[2] + (T[2]-T[1])/3.0 S = append(S, temp1) //S[1]=S2 temp2 := S[1] + (S[1]-S[0])/15.0 C = append(C, temp2) //C[0]=C1 //第四步, k=3 temp0 = 0.0 for j := 1; j < PowIInt(2, 2)+1; j++ { temp0 += fun(a + (2.0*float64(j)-1.0)*(b-a)/(2.0*4.0)) } temp0 = T[2]/2.0 + temp0*(b-a)/(2.0*4.0) T = append(T, temp0) //T[3]=T8 temp1 = T[3] + (T[3]-T[2])/3.0 S = append(S, temp1) //S[2]=S4 temp2 = S[2] + (S[2]-S[1])/15.0 C = append(C, temp2) //C[1]=C2 temp3 := C[1] + (C[1]-C[0])/63.0 R = append(R, temp3) //R[0]=R1 //进入Rumberg循环 for i := 1; i < Nn; i++ { temp0 = 0.0 for j := 1; j < PowIInt(2, i+2)+1; j++ { temp0 += fun(a + (2.0*float64(j)-1.0)*(b-a)/(2.0*PowIIntF(2, i+2))) } temp0 = T[i+2]/2.0 + temp0*(b-a)/(2.0*PowIIntF(2, i+2)) T = append(T, temp0) //T[i+3] temp1 = T[i+3] + (T[i+3]-T[i+2])/3.0 S = append(S, temp1) //S[i+2] temp2 = S[i+2] + (S[i+2]-S[i+1])/15.0 C = append(C, temp2) //C[i+1] temp3 = C[i+1] + (C[i+1]-C[i])/63.0 R = append(R, temp3) //R[i] if math.Abs(R[i]-R[i-1]) < tol { return R[i], true } } return 0.0, false }