// InterpLagrangeFunc /* ------------------------------------------------------ 作者 : Black Ghost 日期 : 2018-12-4 版本 : 0.0.0 ------------------------------------------------------ 求解n次拉格朗日Lagrange插值方程系数,拟合n+1个数据点 满阶插值,即阶数为给定点数-1(因不能确定非满阶时所选取的 插值点是否合理) 理论: n omega0n+1(x) Ln(x) = Sum(----------------------) k=0 (x-xk)*omega1n+1(xk) n omega0n+1(x) = Prod(x-xi) i=0 n omega1n+1(xk) = Prod (xk-xi) i=0,i!=k 参考 李信真, 车刚明, 欧阳洁, 等. 计算方法. 西北工业大学 出版社, 2000, pp 94-100. ------------------------------------------------------ 输入 : A 数据点矩阵,(n+1)x2,第一列xi;第二列yi 输出 : B 插值系数矩阵,(n+1)x1,0~n err 解出标志:false-未解出或达到步数上限; true-全部解出 ------------------------------------------------------ */ package goNum //计算分母 func omega1_InterpLagrangeFunc(A Matrix, k, n int) float64 { var sol float64 = 1.0 for i := 0; i <= n; i++ { if i != k { sol = sol * (A.GetFromMatrix(k, 0) - A.GetFromMatrix(i, 0)) } } return sol } //计算分子并由高阶到低阶排序 func omega0_InterpLagrangeFunc(A Matrix, k, n int) Matrix { B := ZeroMatrix(n+1, 1) //第零阶 x-x0 if k == 0 { //如果k==0,则从x1循环 B.SetMatrix(0, 0, -1.0*A.GetFromMatrix(1, 0)) B.SetMatrix(1, 0, 1.0) } if k > 0 { //如果k>0,则从x0循环 B.SetMatrix(0, 0, -1.0*A.GetFromMatrix(0, 0)) B.SetMatrix(1, 0, 1.0) } //其他i!=k阶 for i := 1; i <= n; i++ { if (i != k) && ((k > 0) || ((k == 0) && (i > 1))) { if k < i { CA := ZeroMatrix(i+1, 1) //实际i+1行 CB := ZeroMatrix(i+1, 1) //实际i行 //先用x乘以之前每一项,相当于给每一项提升一阶,i+1 for ii := 1; ii < i+1; ii++ { //单列可以这样,否则只能用SetMatrix和GetFromMatrix方法 CA.Data[ii] = B.Data[ii-1] } //再用-xi乘以B的每一有效项,i for ii := 0; ii < i; ii++ { //单列可以这样,否则只能用SetMatrix和GetFromMatrix方法 CB.Data[ii] = -1.0 * A.GetFromMatrix(i, 0) * B.Data[ii] } //同阶相加赋予B for ii := 0; ii < i+1; ii++ { B.Data[ii] = CA.Data[ii] + CB.Data[ii] } } else { // k > i CA := ZeroMatrix(i+2, 1) //实际i+2行 CB := ZeroMatrix(i+2, 1) //实际i+1行 //先用x乘以之前每一项,相当于给每一项提升一阶,i+1 for ii := 1; ii < i+2; ii++ { //单列可以这样,否则只能用SetMatrix和GetFromMatrix方法 CA.Data[ii] = B.Data[ii-1] } //再用-xi乘以B的每一有效项,i+1 for ii := 0; ii < i+1; ii++ { //单列可以这样,否则只能用SetMatrix和GetFromMatrix方法 CB.Data[ii] = -1.0 * A.GetFromMatrix(i, 0) * B.Data[ii] } //同阶相加赋予B for ii := 0; ii < i+2; ii++ { B.Data[ii] = CA.Data[ii] + CB.Data[ii] } } } } return B } // InterpLagrangeFunc 求解n次拉格朗日Lagrange插值方程系数,拟合n+1个数据点 func InterpLagrangeFunc(A Matrix) (Matrix, bool) { /* 求解n次拉格朗日Lagrange插值方程系数,拟合n+1个数据点 输入 : A 数据点矩阵,(n+1)x2,第一列xi;第二列yi 输出 : B 插值系数矩阵,(n+1)x1 err 解出标志:false-未解出或达到步数上限; true-全部解出 */ //阶数 n := A.Rows - 1 B := ZeroMatrix(n+1, 1) //最终系数矩阵 var err bool = false //计算系数矩阵 for k := 0; k <= n; k++ { //1. 计算分母和系数乘积 temp0 := A.GetFromMatrix(k, 1) / omega1_InterpLagrangeFunc(A, k, n) //2. 计算分子并乘以上一步的结果,由高阶到低阶排序 temp1 := omega0_InterpLagrangeFunc(A, k, n) for i := 0; i < temp1.Rows; i++ { temp1.Data[i] = temp1.Data[i] * temp0 } //3. 累加 for i := 0; i < B.Rows; i++ { B.Data[i] += temp1.Data[i] } } err = true return B, err }