rpc 非线性方法
This commit is contained in:
@@ -3,11 +3,19 @@ package producer
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gonum.org/v1/gonum/mat"
|
||||
)
|
||||
|
||||
type VX struct {
|
||||
v float64
|
||||
x mat.VecDense
|
||||
}
|
||||
|
||||
const epsilon = 1e-4
|
||||
|
||||
func normalize(v *mat.VecDense) (*mat.VecDense, float64, float64) {
|
||||
var vOff, vScale float64
|
||||
vOff = mat.Sum(v) / float64(v.Len())
|
||||
@@ -34,102 +42,102 @@ func solveCoefficients(f, latVec, lonVec, heightVec *mat.VecDense) ([]float64, e
|
||||
for i := 0; i < n; i++ {
|
||||
weights.SetDiag(i, 1.0)
|
||||
}
|
||||
|
||||
// 计算初始值
|
||||
var x0 mat.VecDense
|
||||
w2 := mat.NewDiagDense(n, nil)
|
||||
for i := 0; i < n; i++ {
|
||||
w2.SetDiag(i, weights.At(i, i)*weights.At(i, i))
|
||||
}
|
||||
var MtW2 mat.Dense
|
||||
MtW2.Mul(M.T(), w2)
|
||||
var MtW2M mat.Dense
|
||||
MtW2M.Mul(&MtW2, M)
|
||||
invMtW2M, err := invertRPCMatrix(&MtW2M)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var MtW2F mat.VecDense
|
||||
MtW2F.MulVec(&MtW2, f)
|
||||
x0.MulVec(invMtW2M, &MtW2F)
|
||||
|
||||
numerator := mat.NewVecDense(20, nil)
|
||||
denominator := mat.NewVecDense(20, nil)
|
||||
denominator.SetVec(0, 1.0)
|
||||
numerator.SetVec(0, x0.AtVec(0))
|
||||
for i := 1; i < 20; i++ {
|
||||
numerator.SetVec(i, x0.AtVec(i))
|
||||
denominator.SetVec(i, x0.AtVec(i+19))
|
||||
}
|
||||
|
||||
num, den, err := solveNelderMead(numerator, denominator, f, latVec, lonVec, heightVec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var coeffs []float64
|
||||
coeffs = append(coeffs, num.RawVector().Data...)
|
||||
for i := 1; i < 20; i++ {
|
||||
coeffs = append(coeffs, den.AtVec(i))
|
||||
}
|
||||
return coeffs, nil
|
||||
|
||||
// 迭代
|
||||
var wm mat.Dense
|
||||
var wmx, wf mat.VecDense
|
||||
var x1 mat.VecDense
|
||||
|
||||
var vx []*VX
|
||||
v0 := 0.0
|
||||
iterations := 0
|
||||
var x mat.VecDense
|
||||
// var e0 float64
|
||||
maxIterations := 10
|
||||
|
||||
for iterations < 20 {
|
||||
iterations++
|
||||
|
||||
// w2 = weights^2
|
||||
for iterations < maxIterations {
|
||||
denominator.SetVec(0, 1.0)
|
||||
for idx := 1; idx < 20; idx++ {
|
||||
denominator.SetVec(idx, x0.AtVec(idx+19))
|
||||
}
|
||||
weights = setupWeightMatrix(denominator, latVec, lonVec, heightVec)
|
||||
for i := 0; i < n; i++ {
|
||||
w2.SetDiag(i, weights.At(i, i)*weights.At(i, i))
|
||||
}
|
||||
|
||||
// x = (M^T * w2 * M)^-1 * M^T * w2 * R
|
||||
var MtW2 mat.Dense
|
||||
MtW2.Mul(M.T(), w2)
|
||||
var MtW2M mat.Dense
|
||||
MtW2M.Mul(&MtW2, M)
|
||||
|
||||
invMtW2M, err := invertRPCMatrix(&MtW2M)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var MtW2F mat.VecDense
|
||||
MtW2F.MulVec(&MtW2, f)
|
||||
x1.MulVec(invMtW2M, &MtW2F)
|
||||
|
||||
x.MulVec(invMtW2M, &MtW2F)
|
||||
wm.Mul(weights, M)
|
||||
wmx.MulVec(&wm, &x1)
|
||||
wf.MulVec(weights, f)
|
||||
wmx.SubVec(&wmx, &wf)
|
||||
wmx.MulElemVec(&wmx, &wmx)
|
||||
v := math.Sqrt(mat.Max(&wmx))
|
||||
log.Println("iteration:", iterations, "v-err:", v)
|
||||
|
||||
numerator := mat.NewVecDense(20, nil)
|
||||
denominator := mat.NewVecDense(20, nil)
|
||||
numerator.SetVec(0, x.AtVec(0))
|
||||
denominator.SetVec(0, 1.0)
|
||||
for idx := 1; idx < 20; idx++ {
|
||||
numerator.SetVec(idx, x.AtVec(idx))
|
||||
denominator.SetVec(idx, x.AtVec(idx+19))
|
||||
}
|
||||
|
||||
weights = setupWeightMatrix(denominator, latVec, lonVec, heightVec)
|
||||
|
||||
// residual = m.t()*w2*(m*tempCoeff-r);
|
||||
// var temp0, temp1, residual mat.VecDense
|
||||
// temp0.MulVec(M, &x)
|
||||
// temp1.SubVec(&temp0, f)
|
||||
// residual.MulVec(&MtW2, &temp1)
|
||||
// var square mat.Dense
|
||||
// square.Mul(residual.T(), &residual)
|
||||
// residualValue := math.Sqrt(square.At(0, 0))
|
||||
// if residualValue < 0.0001 {
|
||||
// break
|
||||
// }
|
||||
|
||||
// fmt.Printf("residual value: %.16f\n", residualValue)
|
||||
// fmt.Printf("iterations: %d\n", iterations)
|
||||
|
||||
e := 0.0
|
||||
for i := 0; i < n; i++ {
|
||||
Rcal := project(numerator, denominator, latVec.AtVec(i), lonVec.AtVec(i), heightVec.AtVec(i))
|
||||
e += math.Pow(Rcal-f.AtVec(i), 2)
|
||||
}
|
||||
e = math.Sqrt(e / float64(n))
|
||||
fmt.Println("iterations:", iterations, "r error:", e)
|
||||
|
||||
if e < 1e-5 {
|
||||
vx = append(vx, &VX{v: v, x: x1})
|
||||
if math.Abs(v-v0) < epsilon {
|
||||
break
|
||||
}
|
||||
|
||||
// dnum := mat.NewVecDense(20, nil)
|
||||
// b0, b1 := true, true
|
||||
// dden := mat.NewVecDense(19, nil)
|
||||
// for i := 0; i < n; i++ {
|
||||
// dnum.SetVec(i, math.Abs(numerator.AtVec(i)-numerator0.AtVec(i)))
|
||||
// numerator0.SetVec(i, numerator.AtVec(i))
|
||||
// fmt.Println("dnum:", i, dnum.AtVec(i))
|
||||
// if dnum.AtVec(i) > 0.000001 {
|
||||
// b0 = false
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// for i := 1; i < n; i++ {
|
||||
// dden.SetVec(i, math.Abs(denominator.AtVec(i)-denominator0.AtVec(i)))
|
||||
// denominator0.SetVec(i, denominator.AtVec(i))
|
||||
// if dden.AtVec(i) > 0.000001 {
|
||||
// b1 = false
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
|
||||
// if b0 && b1 {
|
||||
// break
|
||||
// }
|
||||
x0 = x1
|
||||
v0 = v
|
||||
iterations++
|
||||
}
|
||||
|
||||
log.Println("iterations:", iterations)
|
||||
if iterations == maxIterations {
|
||||
sort.Slice(vx, func(i, j int) bool {
|
||||
return vx[i].v < vx[j].v
|
||||
})
|
||||
x0 = vx[0].x
|
||||
log.Printf("select min v-err: %.8f", vx[0].v)
|
||||
}
|
||||
|
||||
return mat.Col(nil, 0, &x), nil
|
||||
return mat.Col(nil, 0, &x0), nil
|
||||
}
|
||||
|
||||
func setupSystemOfEquations(Rn, latVec, lonVec, heightVec *mat.VecDense) *mat.Dense {
|
||||
@@ -152,7 +160,7 @@ func setupSystemOfEquations(Rn, latVec, lonVec, heightVec *mat.VecDense) *mat.De
|
||||
B.Set(i, 7, L*L)
|
||||
B.Set(i, 8, P*P)
|
||||
B.Set(i, 9, H*H)
|
||||
B.Set(i, 10, P*L*H)
|
||||
B.Set(i, 10, L*P*H)
|
||||
B.Set(i, 11, L*L*L)
|
||||
B.Set(i, 12, L*P*P)
|
||||
B.Set(i, 13, L*H*H)
|
||||
@@ -171,7 +179,7 @@ func setupSystemOfEquations(Rn, latVec, lonVec, heightVec *mat.VecDense) *mat.De
|
||||
B.Set(i, 26, -L*L*r)
|
||||
B.Set(i, 27, -P*P*r)
|
||||
B.Set(i, 28, -H*H*r)
|
||||
B.Set(i, 29, -P*L*H*r)
|
||||
B.Set(i, 29, -L*P*H*r)
|
||||
B.Set(i, 30, -L*L*L*r)
|
||||
B.Set(i, 31, -L*P*P*r)
|
||||
B.Set(i, 32, -L*H*H*r)
|
||||
@@ -206,7 +214,7 @@ func setupWeightMatrix(coeffs, latVec, lonVec, heightVec *mat.VecDense) *mat.Dia
|
||||
row.Set(i, 7, L*L)
|
||||
row.Set(i, 8, P*P)
|
||||
row.Set(i, 9, H*H)
|
||||
row.Set(i, 10, P*L*H)
|
||||
row.Set(i, 10, L*P*H)
|
||||
row.Set(i, 11, L*L*L)
|
||||
row.Set(i, 12, L*P*P)
|
||||
row.Set(i, 13, L*H*H)
|
||||
|
||||
Reference in New Issue
Block a user