Files
sjy01-image-proc/pkg/producer/rpc_optimize.go
2024-08-30 17:01:33 +08:00

65 lines
1.8 KiB
Go

package producer
import (
"fmt"
log "github.com/sirupsen/logrus"
"gonum.org/v1/gonum/mat"
"gonum.org/v1/gonum/optimize"
)
type NormElements struct {
LineOff, SampOff, LatOff, LonOff, HeightOff float64
LineScale, SampScale, LatScale, LonScale, HeightScale float64
}
func objectiveFunc(numerator, denominator, f, latVec, lonVec, heightVec *mat.VecDense) float64 {
errorSquared := 0.0
n := f.Len()
for i := 0; i < n; i++ {
predictedV := project(numerator, denominator, latVec.AtVec(i), lonVec.AtVec(i), heightVec.AtVec(i))
errorV := predictedV - f.AtVec(i)
errorSquared += errorV * errorV
}
return errorSquared / float64(n)
}
func solveNelderMead(num, den, f, latVec, lonVec, heightVec *mat.VecDense) (*mat.VecDense, *mat.VecDense, error) {
var initCoeffs []float64 // a0-a19,b1-b19
initCoeffs = append(initCoeffs, num.RawVector().Data...)
for i := 1; i < 20; i++ {
initCoeffs = append(initCoeffs, den.AtVec(i))
}
problem := optimize.Problem{
Func: func(coeffs []float64) float64 {
numerator := mat.NewVecDense(20, nil)
denominator := mat.NewVecDense(20, nil)
denominator.SetVec(0, 1.0)
numerator.SetVec(0, coeffs[0])
for i := 1; i < 20; i++ {
numerator.SetVec(i, coeffs[i])
denominator.SetVec(i, coeffs[i+19])
}
return objectiveFunc(numerator, denominator, f, latVec, lonVec, heightVec)
},
}
result, err := optimize.Minimize(problem, initCoeffs, &optimize.Settings{}, &optimize.NelderMead{})
if err != nil {
log.Error("Error in RPC optimization: ", err)
return nil, nil, err
}
numerator := mat.NewVecDense(20, nil)
denominator := mat.NewVecDense(20, nil)
denominator.SetVec(0, 1.0)
numerator.SetVec(0, result.X[0])
fmt.Println("len of result.X: ", len(result.X))
for i := 1; i < 20; i++ {
numerator.SetVec(i, result.X[i])
denominator.SetVec(i, result.X[i+19])
}
return numerator, denominator, nil
}