| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- package main
- import (
- "math"
- "math/rand"
- "gonum.org/v1/gonum/optimize"
- "gonum.org/v1/plot"
- "gonum.org/v1/plot/plotter"
- "gonum.org/v1/plot/plotutil"
- "gonum.org/v1/plot/vg"
- )
- func main() {
- var a, b float64 = 0.7, 3
- points1 := plotter.XYs{}
- points2 := plotter.XYs{}
- for i := 0; i <= 10; i++ {
- points1 = append(points1, plotter.XY{
- X: float64(i),
- Y: a*float64(i) + b,
- })
- points2 = append(points2, plotter.XY{
- X: float64(i),
- Y: a*float64(i) + b + (2*rand.Float64() - 1),
- })
- }
- result, err := optimize.Minimize(optimize.Problem{
- Func: func(x []float64) float64 {
- if len(x) != 2 {
- panic("illegal x")
- }
- a := x[0]
- b := x[1]
- var sum float64
- for _, point := range points2 {
- y := a*point.X + b
- sum += math.Abs(y - point.Y)
- }
- return sum
- },
- }, []float64{1, 1}, &optimize.Settings{}, &optimize.NelderMead{})
- if err != nil {
- panic(err)
- }
- fa, fb := result.X[0], result.X[1]
- points3 := plotter.XYs{}
- for i := 0; i <= 10; i++ {
- points3 = append(points3, plotter.XY{
- X: float64(i),
- Y: fa*float64(i) + fb,
- })
- }
- plt := plot.New()
-
- plt.Y.Min, plt.X.Min, plt.Y.Max, plt.X.Max = 0, 0, 10, 10
- if err := plotutil.AddLinePoints(plt,
- "line1", points1,
- "line2", points2,
- "line3", points3,
- ); err != nil {
- panic(err)
- }
- if err := plt.Save(5*vg.Inch, 5*vg.Inch, "10-optimize-fit.png"); err != nil {
- panic(err)
- }
- }
|