1 Star 0 Fork 63

fisher / goNum

forked from 黑影 / goNum 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
InterpLagrangeFunc_test.go 4.62 KB
一键复制 编辑 原始数据 按行查看 历史
黑影 提交于 2019-03-01 10:10 . update comments
// InterpLagrangeFunc_test
/*
------------------------------------------------------
作者 : 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_test
import (
"testing"
"github.com/chfenger/goNum"
)
//计算分母
func omega1_InterpLagrangeFunc(A goNum.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 goNum.Matrix, k, n int) goNum.Matrix {
B := goNum.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 := goNum.ZeroMatrix(i+1, 1) //实际i+1行
CB := goNum.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 := goNum.ZeroMatrix(i+2, 1) //实际i+2行
CB := goNum.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 goNum.Matrix) (goNum.Matrix, bool) {
/*
求解n次拉格朗日Lagrange插值方程系数,拟合n+1个数据点
输入 :
A 数据点矩阵,(n+1)x2,第一列xi;第二列yi
输出 :
B 插值系数矩阵,(n+1)x1
err 解出标志:false-未解出或达到步数上限;
true-全部解出
*/
//阶数
n := A.Rows - 1
B := goNum.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
}
func BenchmarkInterpLagrangeFunc(b *testing.B) {
A23 := goNum.NewMatrix(3, 2, []float64{0.0, 1.0,
1.0, 2.0,
2.0, 3.0})
for i := 0; i < b.N; i++ {
InterpLagrangeFunc(A23)
}
}
Go
1
https://gitee.com/fishersyu/goNum.git
git@gitee.com:fishersyu/goNum.git
fishersyu
goNum
goNum
master

搜索帮助